﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using VideoLan;
using System.Web;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Threading;
using Microsoft.Win32;
using System.Net.NetworkInformation;
using System.Timers;

namespace MulticastTV
{
    public partial class Form1 : Form
    {
        #region Pinvoke
        //PINVOKE for preventing power off
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
        [FlagsAttribute]
        public enum EXECUTION_STATE : uint
        {
            ES_SYSTEM_REQUIRED = 0x00000001,
            ES_DISPLAY_REQUIRED = 0x00000002,
            // Legacy flag, should not be used.
            // ES_USER_PRESENT   = 0x00000004,
            ES_CONTINUOUS = 0x80000000,
            ES_AWAYMODE_REQUIRED = 0x00000040
        }

        private const int SW_SHOWNOACTIVATE = 4;
        private const int HWND_TOPMOST = -1;
        private const uint SWP_NOACTIVATE = 0x0010;
        private const int SW_HIDE = 0;

        //PINVOKE for disabling screen saver
        [DllImport("user32", CharSet = CharSet.Auto)]
        private static extern bool SystemParametersInfo(int uAction, bool uParam, int lpvParam, int fuWinIni);

        [DllImport("user32", CharSet = CharSet.Auto)]
        private static extern bool SystemParametersInfo(int uAction, int uParam, bool lpvParam, int fuWinIni);
        private const int SPI_SETSCREENSAVEACTIVE = 17;
        private const int SPIF_SENDWININICHANGE = 0x02;

        [DllImport("user32.dll")]
        private static extern int GetDoubleClickTime();

        // for wallpaper
        // [DllImport("user32.dll")]
        // private static extern IntPtr GetDesktopWindow();

        #endregion

        #region Enums
        /// <summary>
        /// Aspect ratio enumeration
        /// </summary>
        internal enum Ar : int
        {
            AR_AUTO = 0,
            AR_34 = 1,
            AR_14_9 = 2,
            AR_16_10 = 3,
            AR_16_9 = 4
        }
        /// <summary>
        /// Crop ratio enumeration
        /// Vista and CS are abbreviations fo Cinemascope and VistaVision
        /// </summary>
        internal enum Mask : int
        {
            CROP_NOMASK = 0,
            CROP_34 = 1,
            CROP_1_37 = 2, // 48:35
            CROP_14_9 = 3,
            CROP_VISTA1 = 4, 
            CROP_16_9 = 5,
            CROP_16_9_1 = 6,
            CROP_VISTA2 = 7,
            CROP_CS = 8,
        }

        internal enum Zoom : int
        {
            ZOOM_NOZOOM = 0,
            ZOOM_1_0_5 = 1,
            ZOOM_1_1 = 2,
            ZOOM_1_2 = 3,
            ZOOM_1_3 = 4,
            ZOOM_1_4 = 5,
            ZOOM_1_5 = 6,
            ZOOM_1_6 = 7,
            ZOOM_1_7 = 8,
            ZOOM_1_8 = 9,
            ZOOM_1_9 = 10,
            ZOOM_2_0 = 11
        }

        /// <summary>
        /// Picture settings
        /// </summary>
        internal enum PictSet : int
        {
            EXIT = 0,
            ZOOM = 1,
            POSITION = 2,
            MASK = 3,
            RESET = 4
        }

        internal enum TTX : int 
        {
            OFF = 0,
            ON = 1,
            TRANSPARENT = 2
           }

        #endregion

        #region Global variables

        /// <summary>
        /// Change channel delay, when channel is changed by mouse wheel
        /// </summary>
        public const int changeChannelTimer = 300;
        /// <summary>
        /// Application startup path
        /// </summary>
        string path;
        /// <summary>
        /// Rec folder
        /// </summary>
        string recfolder;
        /// <summary>
        /// Skip hidden rows
        /// </summary>
        string rowfilter;
        /// <summary>
        /// Current selected channel data
        /// </summary>
        public ChannelData curcd;
        /// <summary>
        /// Previous selected channel data
        /// </summary>
        public ChannelData prevcd;
        /// <summary>
        /// List of Groups, including special groups - @ prefix
        /// </summary>
        public List<string> NodeList = new List<string>();
        /// <summary>
        /// Audio list
        /// </summary>
        public List<string> AudioList = new List<string>();
        /// <summary>
        /// Current aspect ratio
        /// </summary>
        public string curar = "default";
        /// <summary>
        /// Current node
        /// </summary>
        string curnode = "@All";
        /// <summary>
        /// Audio language sort
        /// </summary>
        string audiosort = "";
        /// <summary>
        /// Previous window mode
        /// </summary>
        string prevmode = "";
        /// <summary>
        /// Current aspect ratio (cycle) 
        /// </summary>
        int car = 0;
        /// <summary>
        /// Current mask
        /// </summary>
        int cmask = 0;
        /// <summary>
        /// Current zoom
        /// </summary>
        int czoom = 0;
        /// <summary>
        /// Current picture settings like zoom, position, mask
        /// </summary>
        int cPictSet = 0;
        /// <summary>
        /// Teletext mode 
        /// </summary>
        bool teletextMode = false;
        short cttx = 0;
        /// <summary>
        /// Is osd shown?
        /// </summary>
        bool osdshown;
        /// Is mouse visible?
        /// </summary>
        public bool mouseshown = true;
         /// <summary>
        /// Number of PIP instances
        /// </summary>
        public int pipInstances = 0;
        /// <summary>
        /// Volume value
        /// </summary>
        public int volume = 7;
        /// <summary>
        /// Previous volume value
        /// </summary>
        int prevvolume;
        // mouse status
        /// <summary>
        /// Is mouse left button down?
        /// </summary>
        bool mouseleft = false;
        /// <summary>
        /// Doble click elapsed (treeview timer)
        /// </summary>
        static bool doubleClickFromTreeElapsed = true;
        /// <summary>
        /// Image list for listview icons
        /// </summary>
        ImageList il;
        // datatables and dataviews
        /// <summary>
        /// Dataview sorted by channel number
        /// </summary>
        DataView dvchan;
        /// <summary>
        /// Dataview sorted by channel number for daily epg form
        /// </summary>
        public DataView dvchanepg;
        /// <summary>
        /// Dataview  sorted by channel names 
        /// </summary>
        DataView dvcname;
        /// <summary>
        /// Dataview sorted by channel groups
        /// </summary>
        DataView dvcgrp;
        /// <summary>
        /// Dataview sorted by channel audio names
        /// </summary>
        DataView dvcaudio;
        /// <summary>
        /// Dataview with favourites
        /// </summary>
        DataView fav;
        /// <summary>
        /// Last PIP vlc instance
        /// </summary>
        IntPtr pip_handle = IntPtr.Zero;
        NetworkInterface MulticastAdapter = null;
        long bytesReceived = 0;
        volatile float speed = 0.0f;
        StringBuilder numpadstr = new StringBuilder();
        StringBuilder ttxnumpad = new StringBuilder();
        string VoutModule= "Direct3d"; // default module

        #endregion

        #region Global instances

        /// <summary>
        /// Vlc instance
        /// </summary>
        public VideoLan.VideoLanClient vlc = null;
        /// <summary>
        /// Player instance
        /// </summary>
        public VideoLan.VlcMediaPlayer player = null;
        /// <summary>
        /// Recording vlc instance
        /// </summary>
        private VideoLan.VideoLanClient vlc_rec;
        /// <summary>
        /// Recording player instance
        /// </summary>
        private VideoLan.VlcMediaPlayer player_rec;
        /// <summary>
        /// Vlc instance used in last opened PIP.
        /// </summary>
        public VlcNewWindowForm pip_last_instance = null;
        /// <summary>
        /// Network statistics
        /// </summary>
        //http stuff
        VlmHttpRequests httpreq = null;
        UdpRelayRequests udprreq = null;
        UnicastConntest contest = null;
        //epg stuff
        /// <summary>
        /// Daily epg Form
        /// </summary>
        EPGWindowDaily daily;
        /// <summary>
        /// Epg class
        /// </summary>
        public Epg epg = null;

        #endregion

        #region Timers
        /// <summary>
        /// Timer for numpad input
        /// </summary>
        System.Windows.Forms.Timer numpad = new System.Windows.Forms.Timer();
        /// <summary>
        /// Mouse hide timer
        /// </summary>
        public System.Windows.Forms.Timer TimerMouseHide = new System.Windows.Forms.Timer();
        /// <summary>
        /// Timer for audio tracks check.
        /// TODO: This should be handled with events.
        /// </summary>
        System.Windows.Forms.Timer TimerStreamInfo = new System.Windows.Forms.Timer();
        /// <summary>
        /// Change channel delay
        /// </summary>
        System.Windows.Forms.Timer TimerChangeChannelDelay = new System.Windows.Forms.Timer();
        /// <summary>
        /// Timer that prevents two time epg refresh from treeview
        /// </summary>
        System.Windows.Forms.Timer TimerEpgTreeview = new System.Windows.Forms.Timer();
        /// <summary>
        /// Channel surfing timer
        /// </summary>
        System.Windows.Forms.Timer TimerSurf = new System.Windows.Forms.Timer();
        /// <summary>
        /// Epg listview current item timer
        /// </summary>
        System.Windows.Forms.Timer TimerEpgListview = new System.Windows.Forms.Timer();
        /// <summary>
        /// Network monitor timer for gui refresh
        /// </summary>
        System.Windows.Forms.Timer TimerNetMonitorGui = new System.Windows.Forms.Timer();
        /// <summary>
        /// Network monitor timer
        /// </summary>
        System.Timers.Timer TimerNetMonitor;

        #endregion

        #region Delegates
        public delegate void delegateNoParams();
        public delegate void changeChannelFromTimer(ChannelData cd, string sender);
        public delegate void delegateEpgupdate(epgResult er);
        public delegate void delegateEpgDetNext(bool next, bool first, bool reset);
        #endregion

        #region Gui Methods

        /// <summary>
        /// Current traffic speed on selected network card
        /// </summary>
        public float currentSpeed
        {
            get { return speed; }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="pth">Application startup path</param>
        /// <param name="recf">Recording folder</param>
        public Form1(string pth, string recf)
        {
            InitializeComponent();
            VoutModule = Properties.Settings.Default.VideoOutV3;
            path = pth;
            recfolder = recf;
        }

        /// <summary>
        /// Osd and mask z order
        /// </summary>
        private void zorder()
        {
            splitContainer1.Panel1.Controls.SetChildIndex(panel1, 0);
            splitContainer1.Panel1.Controls.SetChildIndex(panel4, 1); //epg
            splitContainer1.Panel1.Controls.SetChildIndex(panel5, 2);
            splitContainer1.Panel1.Controls.SetChildIndex(label2, 3);
            splitContainer1.Panel1.Controls.SetChildIndex(label1, 4);
            splitContainer1.Panel1.Controls.SetChildIndex(panel3, 5);
            splitContainer1.Panel1.Controls.SetChildIndex(panel2, 6);
            splitContainer1.Panel1.Controls.SetChildIndex(pictureBox1, 7);
        }

        /// <summary>
        /// Form load
        /// </summary>
        public void Form1_Load(object sender, EventArgs e)
        {
            // decrypt password
            PasswordEncription.decrypt();

            // load channel settings
            ChannelSettings.loadFromFile();

            this.KeyPreview = true;

            // http
            httpreq = new VlmHttpRequests();
            udprreq = new UdpRelayRequests();
            contest = new UnicastConntest();

            listView1.CreateControl();
            pictureBox1.CreateControl();

            // daily epg window (full screen)
            daily = new EPGWindowDaily(this);

            // pop-up epg window
            PopUpInit();

            // dll stuff - do we have plugin listed in settings conf
            // Web epg plugins
            // Call the find plugins routine, to search in Plugins Folder
            Types.AvailablePlugin selectedPlugin = null;
            if (Directory.Exists(path + @"\webepgplugins"))
                GlobalP.Plugins.findPlugins(path + @"\webepgplugins");
 
            selectedPlugin = GlobalP.Plugins.AvailablePlugins.Find(Properties.Settings.Default.EPGPlugin);
            if (selectedPlugin != null)
                enableEpg();

            //osd window
            OsdInit();

            //Timers init
            // numpad timer init 
            numpad.Interval = 1000;
            numpad.Tick += new EventHandler(numpad_Tick);

            TimerMouseHide.Interval = 15000;
            TimerMouseHide.Tick += new EventHandler(TimerMouseHide_Tick);

            TimerStreamInfo.Interval = 1400;
            TimerStreamInfo.Tick += new EventHandler(TimerStreamInfo_Tick);

            TimerChangeChannelDelay.Interval = changeChannelTimer;
            TimerChangeChannelDelay.Tick += new EventHandler(TimerChangeChannelDelay_Tick);

            TimerEpgTreeview.Interval = GetDoubleClickTime() + 100;
            TimerEpgTreeview.Tick += new EventHandler(TimerDataGrid_Tick);

            TimerSurf.Interval = 7000;
            TimerSurf.Tick += new EventHandler(TimerSurf_Tick);

            TimerEpgListview.Interval = 20000;
            TimerEpgListview.Tick += new EventHandler(TimerEpgListview_Tick);

            TimerNetMonitorGui.Interval = 1000;
            TimerNetMonitorGui.Tick += new EventHandler(TimerNetMonitorGui_Tick);

            getInterfaceStatistics();
            
            // statustrip
            statustripInfo();

            if (Properties.Settings.Default.EnableEpgplugin)
                TimerEpgListview.Start();

            // volume settings
            volume = Properties.Settings.Default.LastVolume;
            prevvolume = volume;

            // some additional events
            dataGridView1.CellMouseDoubleClick += new DataGridViewCellMouseEventHandler(dataGridView1_CellMouseDoubleClick);
            dataGridView1.CellMouseClick += new DataGridViewCellMouseEventHandler(dataGridView1_CellMouseClick); ;
            SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);
            treeView1.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(treeView1_NodeMouseDoubleClick);
            pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            dataGridView1.MouseWheel += new MouseEventHandler(dataGridView1_MouseWheel);

            // Dataviews for sorting (menustrip sortings)
            fillSortings();
            
            ChannelTable.menu.Tables["Menu"].DefaultView.Sort = ChannelTable.menu.Tables["Menu"].Columns[1].ColumnName;
            //data bindings (bindingsource is used by channel table)
            bindingSource1.DataSource = ChannelTable.menu.Tables["Menu"];

            // favourites dataview (TransparentMenuTable: each line one ip)
            string fav_filter = ChannelTable.menu.Tables["Menu"].Columns[5].ColumnName + "= true AND " + rowfilter;
            fav = new DataView(ChannelTable.menu.Tables["Menu"], fav_filter, ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName, DataViewRowState.CurrentRows);

            // Populate strip menus.
            populateFavmenu("name"); // we must call it first because of index 0
            populateMenu("channel", "rightmenu");

            // channel datagridview
            dataGridView1.Columns[0].DataPropertyName = "Chan";
            dataGridView1.Columns[1].DataPropertyName = "Name";
            dataGridView1.Columns[2].DataPropertyName = "Group";
            dataGridView1.DataSource = bindingSource1;

            // table colors
            dgwColors();
            dataGridView1.Columns[0].Visible = false;
            dataGridView1.Columns[3].Visible = false;
            dataGridView1.Columns[4].Visible = false;
            dataGridView1.Columns[5].Visible = false;
            dataGridView1.Columns[6].Visible = false;
            dataGridView1.Columns[7].Visible = false;
            dataGridView1.Columns[8].Visible = false;

            // listview
            listView1.ContextMenuStrip = contextMenuStrip2;
            listView1.ShowItemToolTips = true;
            listView1.View = Properties.Settings.Default.EPGListView;
            updateAllListviewViews();
            listView1.TileSize = new Size(Math.Max(120, this.Width - Properties.Settings.Default.splitter - 50), Properties.Settings.Default.EPGHighFont.Height);

            if (!Properties.Settings.Default.Multicast)
            {
                recordNowF7ToolStripMenuItem.Enabled = false;
                showInNewWindowToolStripMenuItem.Enabled = false;
                showInNewWindowToolStripMenuItem1.Enabled = false;
                pIPToolStripMenuItem.Enabled = false;
            }

            // Populate treeView1.
            populateTreeView();

            // colors
            sidebarcolors();

            // epg panel visible
            if (Properties.Settings.Default.EPGView)
            {
                ePGToolStripMenuItem.CheckState = CheckState.Checked;
                splitContainer2.Panel2Collapsed = false;
            }
            else
            {
                ePGToolStripMenuItem.CheckState = CheckState.Unchecked;
                splitContainer2.Panel2Collapsed = true;
            }

            // Disable epg popup if there are no plugins
            if (epg == null)
                Properties.Settings.Default.EpgFs = false;

            // treeview
            if (Properties.Settings.Default.treeviev)
            {
                treeToolStripMenuItem.CheckState = CheckState.Checked;
                splitContainer1.Panel2Collapsed = false;
            }
            else
            {
                treeToolStripMenuItem.CheckState = CheckState.Unchecked;
                splitContainer1.Panel2Collapsed = true;
            }

            il = new ImageList();
            il.Images.Add(Properties.Resources.film_go); //arrow  0
            il.Images.Add(Properties.Resources.Group);   //folder 1
            il.Images.Add(Properties.Resources.film);    //film    2
            il.Images.Add(Properties.Resources.film_add);  //checked 3
            il.Images.Add(Properties.Resources.Movie);  //green folder 4
            il.Images.Add(Properties.Resources.Favorite);   //yellow folder 5
            treeView1.ImageList = il;
            treeView1.SelectedImageIndex = 0;

            // deinterlace checkbox
            if (Properties.Settings.Default.VideoDeinterlaceV4 == "")
                deinterlaceToolStripMenuItem1.CheckState = CheckState.Unchecked;
            else
                deinterlaceToolStripMenuItem1.CheckState = CheckState.Checked;

            // multicast unicast checkboxes
            if (Properties.Settings.Default.Multicast)
            {
                normalToolStripMenuItem.CheckState = CheckState.Checked;
                uToolStripMenuItem.CheckState = CheckState.Unchecked;
            }
            else
            {
                normalToolStripMenuItem.CheckState = CheckState.Unchecked;
                uToolStripMenuItem.CheckState = CheckState.Checked;
            }

            // window position 
            if (!Properties.Settings.Default.LastPosition.IsEmpty && !Properties.Settings.Default.FullScreen)
                this.Location = Properties.Settings.Default.LastPosition;

            // statusbar
            if (Properties.Settings.Default.StatusBarView)
            {
                statusbarToolStripMenuItem.CheckState = CheckState.Checked;
                statusStrip1.Visible = true;
            }
            else
            {
                statusbarToolStripMenuItem.CheckState = CheckState.Unchecked;
                statusStrip1.Visible = false;
            }

            // window mode
            if (Properties.Settings.Default.WindowMode)
            {
                fullscreenToolStripMenuItem.CheckState = CheckState.Checked;
                fullScreenToolStripMenuItem1.CheckState = CheckState.Checked;
                setWindowMode(true);
            }

            //window size
            if (Properties.Settings.Default.LastSize != new Size(0, 0) && !Properties.Settings.Default.FullScreen)
                this.Size = Properties.Settings.Default.LastSize;

            //splitter position
            try
            {
                if (Properties.Settings.Default.splitter != 1 && Properties.Settings.Default.splitter > 0)
                    splitContainer1.SplitterDistance = Properties.Settings.Default.splitter;

                if (Properties.Settings.Default.splitter2 != 1 && Properties.Settings.Default.splitter2 > 0)
                    splitContainer2.SplitterDistance = Properties.Settings.Default.splitter2;
            }
            catch { }

            // full screen 
            if (Properties.Settings.Default.FullScreen)
            {
                fullscreenToolStripMenuItem.CheckState = CheckState.Checked;
                fullScreenToolStripMenuItem1.CheckState = CheckState.Checked;
                Properties.Settings.Default.FullScreen = false;
                setFullScreenMode();
            }

            // vlc ar
            curar = Properties.Settings.Default.LastAr;
            setAr(curar);

            // allwaysontop
            if (Properties.Settings.Default.AllwaysOnTop)
                setAllwaysOnTop(true);
            else
                setAllwaysOnTop(false);

            // osd sizes
            ttxLabelSize();
            recLabelSize();

            restoreLastSelectedChannel();

            zorder();

            // auto start vlc and update epg
            setChannel(curcd, "MAIN");

            //directshow d3d:
            //renderTimer.Interval = 31; // approx 25 fps - no problem if less - when video starts, this timer is disabled
            //renderTimer.Tick += new EventHandler(renderTimer_Tick);

        }


        #region Channel Management and Synchronization

        /// <summary>
        /// Create DataViews with different sortings
        /// </summary>
        private void fillSortings()
        {
            rowfilter = ChannelTable.menu.Tables["Menu"].Columns[6].ColumnName + "=false";
            try
            {
                ChannelTable.menu.Tables["Menu"].DefaultView.RowFilter = rowfilter;
            }
            catch { }
            dvchan = new DataView(ChannelTable.menu.Tables["Menu"], rowfilter, ChannelTable.menu.Tables["Menu"].Columns[1].ColumnName, DataViewRowState.CurrentRows);
            dvchanepg = new DataView(ChannelTable.menu.Tables["Menu"], "", ChannelTable.menu.Tables["Menu"].Columns[1].ColumnName, DataViewRowState.CurrentRows);
            dvcname = new DataView(ChannelTable.menu.Tables["Menu"], rowfilter, ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName, DataViewRowState.CurrentRows);
            dvcgrp = new DataView(ChannelTable.menu.Tables["Menu"], rowfilter, ChannelTable.menu.Tables["Menu"].Columns[3].ColumnName + "," + ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName, DataViewRowState.CurrentRows);
            dvcaudio = new DataView(ChannelTable.menu.Tables["Menu"], rowfilter, ChannelTable.menu.Tables["Menu"].Columns[4].ColumnName + "," + ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName, DataViewRowState.CurrentRows);
            getUniqueGroupsList();
            getUniqueAudioList();
        }

        public void channelManagementReconfiguration()
        {
            dvchan.Dispose();
            dvchanepg.Dispose();
            dvcname.Dispose();
            dvcgrp.Dispose();
            dvcaudio.Dispose();
            fillSortings();
            // populate strip menus
            populateFavmenu("name"); // we must call it first 
            populateMenu("channel", "rightmenu");
            populateTreeView();
        }

        /// <summary>
        /// Populate menus.
        /// </summary>
        /// <param name="sort">Sort by name,group,number</param>
        /// <param name="sender">Sender</param>
        public void populateMenu(string sort, string sender)
        {
            string srt = sort;
            char[] delimiter = { '+' };
            DataView sortdw = null;

            // Let's create temporary menu
            ToolStripMenuItem temp = new ToolStripMenuItem();

            if (sender == "rightmenu")
            {
                temp.DropDown.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(MenuChannelClicked);
                temp.Text = contextMenuStrip1.Items[1].Text;
            }

            if (srt == "channel")
                sortdw = dvchan;

            else if (srt == "group")
                sortdw = dvcgrp;

            else if (srt == "name")
                sortdw = dvcname;

            string grp = "";
            int prevchannel = 0;
            foreach (DataRowView drv in sortdw)
            {
                ToolStripMenuItem row = new ToolStripMenuItem();
                int channel = (int)drv[1];
                string name = drv[2].ToString();
                string group = drv[3].ToString();
                string audio = drv[4].ToString();
                string ip = drv[0].ToString();
                bool locked = (bool)drv[8];
                bool skip = (bool)drv[6];
                string node;
                if (srt == "group")
                    node = extractFirstGroup(group);
                else
                    node = "@All";
                ChannelData tag = new ChannelData(ip, name, channel, node, locked, skip);

                if (srt == "group" && group != grp)
                {
                    ToolStripItem tsgroup = new ToolStripMenuItem();
                    tsgroup.Text = group;
                    tsgroup.Font = new Font("Arial", 10.0f, FontStyle.Bold);
                    tsgroup.Tag = tag;
                    temp.DropDownItems.Add("-");
                    temp.DropDownItems.Add(tsgroup);
                    temp.DropDownItems.Add("-");
                    grp = group;
                }

                if (channel == prevchannel && channel != 0)
                {
                    row.Text = "       " + name + "   (" + audio + ")";
                    row.Tag = tag;
                    temp.DropDownItems.Add(row);
                }
                else
                {
                    if (srt == "channel")
                        row.Text = channel.ToString() + "   " + name;
                    else
                        row.Text = name;
                    row.Tag = tag;
                    temp.DropDownItems.Add(row);
                }
                prevchannel = channel;
            }

            if (sender == "rightmenu")
            {
                try { contextMenuStrip1.Items.RemoveAt(1); }
                catch { }
                contextMenuStrip1.Items.Insert(1, temp);
            }
            updateSortCheckboxes(srt, sender);
        }

        /// <summary>
        /// Populate favourite toolstrip menu.
        /// </summary>
        /// <param name="sort">Sort by name,group,number</param>
        public void populateFavmenu(string sort)
        {
            ToolStripMenuItem favorite = new ToolStripMenuItem();
            ToolStripMenuItem favorite1 = new ToolStripMenuItem();
            favorite.Image = Properties.Resources.star;
            favorite1.Image = Properties.Resources.star;
            favorite.Text = channelsToolStripMenuItem.DropDown.Items[0].Text;
            favorite1.Text = channelsToolStripMenuItem.DropDown.Items[0].Text;
            favorite.DropDown.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(MenuChannelClicked);
            favorite1.DropDown.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(MenuChannelClicked);

            if (sort == "name")
                fav.Sort = ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName;
            if (sort == "channel")
                fav.Sort = ChannelTable.menu.Tables["Menu"].Columns[1].ColumnName;
            if (sort == "group")
                fav.Sort = ChannelTable.menu.Tables["Menu"].Columns[3].ColumnName;

            string grp = "";
            foreach (DataRowView d in fav)
            {
                int channel = (int)d[1];
                string name = d[2].ToString();
                string group = d[3].ToString();
                string ip = (string)d[0];
                bool locked = (bool)d[8];
                bool skip = (bool)d[6];

                ToolStripMenuItem row = new ToolStripMenuItem();
                ToolStripMenuItem row1 = new ToolStripMenuItem();
                ChannelData cd = new ChannelData(ip, name, channel, "@Fav", locked, skip);

                if (sort == "channel")
                    row.Text = channel + "  " + name;
                else
                    row.Text = name;

                row.Tag = cd;
                if (sort == "channel")
                    row1.Text = channel + "  " + name;
                else
                    row1.Text = name;
                row1.Tag = cd;
                if (sort == "group" && group != grp)
                {
                    favorite.DropDownItems.Add("-");
                    favorite.DropDownItems.Add(row);
                    favorite1.DropDownItems.Add("-");
                    favorite1.DropDownItems.Add(row1);
                    grp = group;
                }
                else
                {
                    favorite.DropDownItems.Add(row);
                    favorite1.DropDownItems.Add(row1);
                }

            }
            try { channelsToolStripMenuItem.DropDownItems.RemoveAt(0); }
            catch { }
            channelsToolStripMenuItem.DropDownItems.Insert(0, favorite);
            try { contextMenuStrip1.Items.RemoveAt(0); }
            catch { }
            contextMenuStrip1.Items.Insert(0, favorite1);
        }

        /// <summary>
        ///Populate treeview.
        /// </summary>
        public void populateTreeView()
        {
            //film arrow  0
            //folder 1
            //film    2
            //checked 3
            //green folder 4
            //yellow folder 5

            treeView1.BeginUpdate();
            treeView1.Nodes.Clear();
            int j = 0; //root nodes

            TreeNode tngfav = new TreeNode();
            tngfav.Text = MLmessages.Favourites;
            tngfav.Name = "@Fav"; //key
            tngfav.ImageIndex = 5;
            tngfav.StateImageIndex = 3;
            tngfav.SelectedImageIndex = 5;
            tngfav.ContextMenuStrip = contextMenuStrip6;
            treeView1.Nodes.Add(tngfav);

            bool sbn = false;

            // ADD favourites
            if (Properties.Settings.Default.FavSort == "names")
            {
                fav.Sort = ChannelTable.menu.Tables["Menu"].Columns[2].ColumnName;
                sbn = true;
            }
            else if (Properties.Settings.Default.FavSort == "numbers")
                fav.Sort = ChannelTable.menu.Tables["Menu"].Columns[1].ColumnName;
            if (fav.Count > 0)
            {
                foreach (DataRowView drf in fav)
                {
                    int channel = (int)drf[1];
                    string name = drf[2].ToString();
                    string group = drf[3].ToString();
                    string audio = drf[4].ToString();
                    string ip = drf[0].ToString();
                    bool locked = (bool)drf[8];
                    bool skip = (bool)drf[6];
                    ChannelData cd = new ChannelData(ip, name, channel, "@Fav", locked, skip);
                    TreeNode tnc = new TreeNode();
                    if (sbn)
                        tnc.Text = name;
                    else
                        tnc.Text = channel.ToString() + " " + name;
                    tnc.Tag = cd;
                    tnc.ImageIndex = 2;
                    tnc.SelectedImageIndex = 0;
                    tnc.StateImageIndex = 3;
                    tnc.ContextMenuStrip = contextMenuStrip4;
                    treeView1.Nodes[j].Nodes.Add(tnc);
                }
                j++;
            }
            else
                j++;

            // ADD All
            TreeNode tngall = new TreeNode();
            tngall.Text = MLmessages.All;
            tngall.Name = "@All"; //key
            tngall.ImageIndex = 4;
            tngall.SelectedImageIndex = 4;
            tngall.StateImageIndex = 3;
            tngall.ContextMenuStrip = contextMenuStrip5;
            filterToolStripMenuItem.DropDown.Items.Clear();
            ToolStripMenuItem allreset = new ToolStripMenuItem();
            allreset.Name = "";
            allreset.Text = MLmessages.All;
            allreset.MouseDown += new MouseEventHandler(audiodd_MouseDown);
            filterToolStripMenuItem.DropDown.Items.Add(allreset);
            // audio menu
            foreach (string audio in AudioList)
            {
                ToolStripMenuItem audiodd = new ToolStripMenuItem();
                audiodd.Name = audio;
                audiodd.Text = audio;
                if (audiodd.Name == audiosort)
                    audiodd.CheckState = CheckState.Checked;

                audiodd.MouseDown += new MouseEventHandler(audiodd_MouseDown);
                filterToolStripMenuItem.DropDown.Items.Add(audiodd);
            }
            treeView1.Nodes.Add(tngall);

            DataView dwaSort = null;
            if (Properties.Settings.Default.AllSortBy == "numbers")
                dwaSort = dvchan;
            else if (Properties.Settings.Default.AllSortBy == "names")
                dwaSort = dvcname;

            if (audiosort != "")
                dwaSort.RowFilter = "audio ='" + audiosort + "' AND " + rowfilter;
            else
                dwaSort.RowFilter = rowfilter;

            foreach (DataRowView dra in dwaSort)
            {
                int channel = (int)dra[1];
                string name = dra[2].ToString();
                string group = dra[3].ToString();
                string audio = dra[4].ToString();
                string ip = dra[0].ToString();
                bool locked = (bool)dra[8];
                bool skip = (bool)dra[6];
                ChannelData cd = new ChannelData(ip, name, channel, "@All", locked, skip);
                TreeNode tnc = new TreeNode();
                if (Properties.Settings.Default.AllSortBy == "numbers")
                    tnc.Text = channel.ToString() + ". " + name;
                else
                    tnc.Text = name;
                tnc.Tag = cd;
                tnc.ImageIndex = 2;
                tnc.SelectedImageIndex = 0;
                tnc.StateImageIndex = 3;
                tnc.ContextMenuStrip = contextMenuStrip4;
                treeView1.Nodes[j].Nodes.Add(tnc);
            }
            j++;

            // ADD rest of the groupes
            foreach (string grp in NodeList)
            {
                if (grp != "@All" && grp != "@Fav" && grp != "")
                {
                    TreeNode tng = new TreeNode();
                    tng.Text = grp;
                    tng.Name = grp; //key
                    tng.StateImageIndex = 3;
                    tng.SelectedImageIndex = 1;
                    tng.ImageIndex = 1;
                    tng.ContextMenuStrip = contextMenuStrip7;
                    treeView1.Nodes.Add(tng);
                }
            }

            DataView dwgSort = null;
            string srt = Properties.Settings.Default.GroupSort;
            if (srt == "numbers")
                dwgSort = dvchan;
            else if (srt == "names")
                dwgSort = dvcname;

            foreach (DataRowView dr in dwgSort)
            {
                int channel = (int)dr[1];
                string name = dr[2].ToString();
                string audio = dr[4].ToString();
                string ip = dr[0].ToString();
                string[] groups = dr[3].ToString().Split(',');
                bool locked = (bool)dr[8];
                bool skip = (bool)dr[6];

                foreach (string grp in groups)
                {
                    ChannelData cd = new ChannelData(ip, name, channel, grp, locked, skip);
                    TreeNode tnc = new TreeNode();
                    if (srt == "names")
                        tnc.Text = name;
                    else
                        tnc.Text = channel.ToString() + ". " + name;
                    tnc.SelectedImageIndex = 0;
                    tnc.StateImageIndex = 3;
                    tnc.Tag = cd;
                    tnc.ImageIndex = 2;
                    tnc.ContextMenuStrip = contextMenuStrip4;

                    if (grp != "")
                        treeView1.Nodes[treeView1.Nodes.IndexOfKey(grp)].Nodes.Add(tnc);
                }
            }
            treeView1.EndUpdate();
        }

        /// <summary>
        ///Search result in treeview.
        /// </summary>
        private void filterTreeView()
        {
            // All node is allways second
            TreeNode All = treeView1.Nodes[1];

            string filter;
            if (textBox1.Text.Length > 0)
            {
                if (textBox1.Text.Length == 1)
                    filter = "name LIKE '" + textBox1.Text + "*' AND " + rowfilter;
                else
                    filter = "name LIKE '%" + textBox1.Text + "%' AND " + rowfilter;

                All.Text = MLmessages.AllSearch;
            }
            else
            {
                filter = rowfilter;
                All.Text = MLmessages.All;
            }

            treeView1.BeginUpdate();

            All.Nodes.Clear();

            DataView dwSort = null;
            if (Properties.Settings.Default.AllSortBy == "numbers")
                dwSort = dvchan;
            else if (Properties.Settings.Default.AllSortBy == "names")
                dwSort = dvcname;

            dwSort.RowFilter = filter;
            foreach (DataRowView dra in dwSort)
            {
                int channel = (int)dra[1];
                string name = dra[2].ToString();
                string group = dra[3].ToString();
                string audio = dra[4].ToString();
                string ip = dra[0].ToString();
                bool locked = (bool)dra[8];
                bool skip = (bool)dra[6];
                ChannelData cd = new ChannelData(ip, name, channel, "@All", locked, skip);
                TreeNode tnc = new TreeNode();
                if (Properties.Settings.Default.AllSortBy == "numbers")
                    tnc.Text = channel.ToString() + ". " + name;
                else
                    tnc.Text = name;
                tnc.Tag = cd;
                tnc.ImageIndex = 2;
                tnc.SelectedImageIndex = 0;
                tnc.StateImageIndex = 3;
                tnc.ContextMenuStrip = contextMenuStrip4;
                All.Nodes.Add(tnc);
            }
            treeView1.EndUpdate();
        }

        /// <summary>
        /// Channel up (alias find next channel)
        /// </summary>
        public void chUpDown(string direction)
        {
            if (direction == "Up")
            {
                if (!splitContainer1.Panel2Collapsed)
                    mk_DOWN();
                else
                {
                    table_DOWN();
                    table_ENTER("DATAGRID_SIM");
                }
            }

            else if (direction == "Down")
            {
                if (!splitContainer1.Panel2Collapsed)
                    mk_UP();
                else
                {
                    table_UP();
                    table_ENTER("DATAGRID_SIM");
                }
            }
        }

        /// <summary>
        /// Select previous channel or set to channel that is currently on PIP.
        /// </summary>
        /// <param name="pipoverride">Swap pictures</param>
        public void prevChan()
        {
            if (pip_last_instance != null && !pip_last_instance.IsDisposed)
            {
                // check if it's not the same channel
                if (pip_last_instance.cd.Ip != curcd.Ip)
                {
                    setChannel(pip_last_instance.cd, "RECALL");
                    return;
                }
            }
            setChannel(prevcd, "RECALL");
        }

        /// <summary>
        /// Update information about current selected channel.
        /// </summary>
        /// <param name="_cd"></param>
        private void currentInfo(ChannelData _cd)
        {
            curcd = new ChannelData(_cd.Ip, _cd.Name, _cd.Num, _cd.Node, _cd.Locked, _cd.Skip);
            curnode = curcd.Node;
        }

        /// <summary>
        /// Mouse or key down. If treeview is not collapsed, we find next channel from treeview.
        /// </summary>
        private void mk_DOWN()
        {
            if (treeView1.SelectedNode == null || treeView1.SelectedNode.Level == 0)
                updateTreeviewWithCurChn(curcd, "MAIN");

            if (treeView1.SelectedNode != null && treeView1.SelectedNode.Level > 0)
            {
                int count = treeView1.SelectedNode.Parent.Nodes.Count;
                if (count > 0)
                {
                    int pindex = treeView1.SelectedNode.Parent.Index;
                    int index = treeView1.SelectedNode.Index;
                    if (treeView1.SelectedNode.Index < count - 1)
                        treeView1.SelectedNode = treeView1.Nodes[pindex].Nodes[index + 1];
                    else
                        treeView1.SelectedNode = treeView1.Nodes[pindex].Nodes[0];
                    mk_SET(treeView1.SelectedNode);
                }
            }
        }

        /// <summary>
        /// Mouse or key up. If treeview is not collapsed, we find previous channel from treeview.
        /// </summary>
        private void mk_UP()
        {
            if (treeView1.SelectedNode == null || treeView1.SelectedNode.Level == 0)
                updateTreeviewWithCurChn(curcd, "MAIN");

            if (treeView1.SelectedNode != null && treeView1.SelectedNode.Level > 0)
            {
                int count = treeView1.SelectedNode.Parent.Nodes.Count;
                if (count > 0)
                {
                    int pindex = treeView1.SelectedNode.Parent.Index;
                    int index = treeView1.SelectedNode.Index;
                    if (treeView1.SelectedNode.Index > 0)
                        treeView1.SelectedNode = treeView1.Nodes[pindex].Nodes[index - 1];
                    else
                        treeView1.SelectedNode = treeView1.Nodes[pindex].Nodes[count - 1];
                    mk_SET(treeView1.SelectedNode);
                }
            }
        }

        private void mk_SET(TreeNode tn)
        {
            ChannelData chandata = (ChannelData)tn.Tag;
            setChannel(chandata, "TREEVIEW_SIM");
        }

        /// <summary>
        /// Select next item in channel table.
        /// </summary>
        private void table_DOWN()
        {
            if (dataGridView1.Rows.Count > 0)
            {
                if (dataGridView1.CurrentRow.Index < dataGridView1.Rows.Count - 1)
                {
                    dataGridView1.CurrentCell.Selected = false;
                    dataGridView1.Rows[dataGridView1.CurrentRow.Index + 1].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[1];
                }
                else
                {
                    dataGridView1.CurrentCell.Selected = false;
                    dataGridView1.Rows[0].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[1];
                }
            }
        }

        /// <summary>
        /// Select previous item in channel table
        /// </summary>
        private void table_UP()
        {
            int count = dataGridView1.Rows.Count;
            if (count > 0)
            {
                if (dataGridView1.CurrentRow.Index > 0)
                {
                    dataGridView1.CurrentCell.Selected = false;
                    dataGridView1.Rows[dataGridView1.CurrentRow.Index - 1].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[1];
                }
                else
                {
                    dataGridView1.CurrentCell.Selected = false;
                    dataGridView1.Rows[count - 1].Selected = true;
                    dataGridView1.CurrentCell = dataGridView1.SelectedCells[1];
                }
            }
        }

        /// <summary>
        /// Change group in channel table.
        /// </summary>
        private void table_LEFT()
        {
            int count = NodeList.Count;
            if (count == 0)
                return;

            int cg = NodeList.IndexOf((string)dataGridView1.Columns[2].HeaderCell.Tag);
            string sortby = "";
            if (cg != -1)
            {
                if (cg - 1 >= 0)
                    sortby = NodeList[cg - 1];
                else
                    sortby = NodeList[count - 1];
            }
            else
                sortby = "";

            tableSort(sortby);
        }

        /// <summary>
        /// Change group in channel table.
        /// </summary>
        private void table_RIGHT()
        {
            int count = NodeList.Count;
            if (count == 0)
                return;

            int cg = NodeList.IndexOf((string)dataGridView1.Columns[2].HeaderCell.Tag);
            string sortby = "";
            if (cg != -1)
            {
                if (cg + 1 < count)
                    sortby = NodeList[cg + 1];
                else
                    sortby = NodeList[0];
            }
            else
                sortby = "";

            tableSort(sortby);
        }

        /// <summary>
        /// Start currently selected item in channel table
        /// </summary>
        /// <param name="sender"></param>
        private void table_ENTER(string sender)
        {
            if (dataGridView1.Rows.Count == 0)
                return;

            string _name = (string)dataGridView1.SelectedCells[2].Value;
            string _ip = (string)dataGridView1.SelectedCells[0].Value;
            string _group = (string)dataGridView1.SelectedCells[3].Value;
            int _channel = (int)dataGridView1.SelectedCells[1].Value;
            bool _locked = (bool)dataGridView1.SelectedCells[8].Value;
            bool _skip = (bool)dataGridView1.SelectedCells[6].Value;
            string tag = (string)dataGridView1.Columns[2].HeaderCell.Tag;
            ChannelData cd = new ChannelData(_ip, _name, _channel, tag, _locked, _skip);
            setChannel(cd, sender);
        }

        private void tableSort(string sortby)
        {
            dataGridView1.Columns[2].HeaderCell.Tag = sortby;

            string headername = "";
            string sort = "";
            string filter = rowfilter;
            if (sortby == "@All")
            {
                sort = "";
                headername = MLmessages.All;
            }
            else if (sortby == "@Fav")
            {
                sort = "";
                headername = MLmessages.Favourites;
                filter = ChannelTable.menu.Tables["Menu"].Columns[5].ColumnName + "= true AND " + rowfilter;
            }
            else
            {
                sort = sortby;
                filter = "Group LIKE '%" + sort + "%' AND " + rowfilter;
                headername = sortby;
            }

            if (bindingSource1.Filter != filter)
            {
                bindingSource1.Filter = filter;
                dataGridView1.Columns[2].HeaderCell.Value = headername;
                //adjust row height
                dataGridView1.Height = panel1.Height;
                dataGridView1.AutoResizeRows();
                preventPartialRows();
            }
        }

        /// <summary>
        /// Update information about last selected channel. Called on application startup.
        /// </summary>
        private void restoreLastSelectedChannel()
        {
            int i=0;
            int index = 0;
            if (Properties.Settings.Default.RememberLastSelectedChan)
                index = dvchan.Find(Properties.Settings.Default.LastChannelNumber);
            if (index != -1)
                i = index;
            if (dvchan.Count > i)
            {
                string grps = (string)dvchan[i][3];
                string nd;
                if (grps.Contains(Properties.Settings.Default.LastNode))
                    nd = Properties.Settings.Default.LastNode;
                else
                    nd ="@All";
                curcd = new ChannelData((string)dvchan[i][0], (string)dvchan[i][2], (int)dvchan[i][1], nd, (bool)dvchan[i][8], (bool)dvchan[i][6]);
            }
            else // empty playlist
                curcd = new ChannelData("", "", 1, "@All", false, false);

        //check if last saved node exists
        if (!NodeList.Contains(curcd.Node))
        {
            curcd.Node = "@All";
            Properties.Settings.Default.LastNode = "@All";
        }
        }

        /// <summary>
        /// Start "ChangeChannel" timer
        /// </summary>
        /// <param name="chandata"></param>
        /// <param name="sender"></param>
        private void setChannel(ChannelData chandata, string sender)
        {
            string channame;
            string ip;
            channame = chandata.Name;
            int chan = chandata.Num;
            ip = chandata.Ip;
            string ti = chan.ToString() + "  " + channame;
            toolStripStatusLabelName.Text = ti;
            chanOSD(ti);
            curnode = chandata.Node;

            if (this.Visible)
            {
                // sync
                if (sender != "TREEVIEW" && sender != "TREEVIEW_SIM")
                    updateTreeviewWithCurChn(chandata, sender);
                if (sender != "DATAGRID" && sender != "DATAGRID_SIM")
                    updateTableWithCurChn(ip, sender);
            }

            if (sender == "DATAGRID_SIM" || sender == "TREEVIEW_SIM")
                TimerChangeChannelDelay.Interval = changeChannelTimer;
            else
                TimerChangeChannelDelay.Interval = 1;

            TimerChangeChannelDelay.Stop();
            TimerChangeChannelDelay.Tag = chandata;
            TimerChangeChannelDelay.Start();
        }

        /// <summary>
        ///Select treeview item that correspondes to current channel (ip and group based).
        ///Ensure that all nodes except current and @All are collapsed. 
        /// </summary>
        /// <param name="ipin">Ip</param>
        /// <param name="sender">Sender</param>
        private void updateTreeviewWithCurChn(ChannelData cd, string sender)
        {
            if (sender == "TREEVIEW")
                return;

            bool collapse = true;
            bool found = false;
            int tnindex = -1;
            int tn1index = -1;

            //treeView1.BeginUpdate();
            foreach (TreeNode tn in treeView1.Nodes)
            {
                collapse = true;
                foreach (TreeNode tn1 in tn.Nodes)
                {
                    ChannelData chandata = (ChannelData)tn1.Tag;
                    string ip = "";
                    if (!found)
                        ip = chandata.Ip;

                    if (ip == cd.Ip)
                    {
                        if (tn.Name != curnode)
                            break;

                        treeView1.SelectedNode = tn1;
                        collapse = false;
                        found = true;
                        tn1index = tn1.Index;
                        tnindex = tn.Index;
                        break;
                    }
                }
                if (collapse && tn.Name != "@All")
                {
                    if (tn.IsExpanded)
                    {
                        tn.Collapse();
                        collapse = true;
                    }
                }
            }
            if (tnindex != -1 && tn1index != -1)
            {
                try
                {
                    if (!treeView1.Nodes[tnindex].Nodes[tn1index].IsVisible)
                        treeView1.Nodes[tnindex].Nodes[tn1index].EnsureVisible();
                }
                catch { }
            }
            //treeView1.EndUpdate();
        }

        /// <summary>
        ///select datatable item that correspondes to current channel (ip based)
        /// </summary>
        /// <param name="ipin">Ip</param>
        /// <param name="sender">Sender</param>
        private void updateTableWithCurChn(string ipin, string sender)
        {
            // uppdate with current node
            tableSort(curnode);
            dataGridView1.ClearSelection();
            foreach (DataGridViewRow dr in dataGridView1.Rows)
            {
                string ip = (string)dr.Cells[0].Value;

                if (ip == ipin)
                {
                    dr.Selected = true;
                    dataGridView1.CurrentCell = dr.Cells[1];
                    break;
                }
            }
        }

        /// <summary>
        ///Build numpad input
        /// </summary>
        /// <param name="ch">Digit</param>
        public void prepearenum(int ch)
        {
            numpad.Start();
            numpadstr.Append(ch);
            chanOSDinput();
            if (numpadstr.Length >= 3)
            {
                numpad.Stop();
                chantoip(int.Parse(numpadstr.ToString()));
                numpadstr.Length = 0;
            }
        }

        private void numpadInput(int num)
        {
            if (!teletextMode)
                prepearenum(num);
            else
                ttxNuminput(num);
        }

        private void numpad_Tick(Object sender, EventArgs e)
        {
            // Timer sets channel if no additional digit is entered.
            chantoip(int.Parse(numpadstr.ToString()));
            numpad.Stop();
            numpadstr.Length = 0;
        }

        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //adjust row height
            dataGridView1.Height = panel1.Height;
            dataGridView1.AutoResizeRows();
            preventPartialRows();
        }

        private void MenuChannelClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            //temp, favourites, all
            ChannelData chandata = (ChannelData)e.ClickedItem.Tag;
            setChannel(chandata, "MENU");
        }

        private void byGroupToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            populateFavmenu("group");
            populateMenu("group", "rightmenu");
        }

        private void byChannelToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            populateFavmenu("channel");
            populateMenu("channel", "rightmenu");
            dvchan.RowFilter = rowfilter;
        }

        private void byNameToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            populateFavmenu("name");
            populateMenu("name", "rightmenu");
            dvchan.RowFilter = rowfilter;
        }

        private void dataGridView1_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex == -1)
                return;

            if (e.Button == MouseButtons.Left && Properties.Settings.Default.MouseSetChannel == 2)
                table_ENTER("DATAGRID");
        }
       
        /// <summary>
        /// Update sorting checkboxes (right click menu)
        /// </summary>
        /// <param name="sortorder">Sort order</param>
        /// <param name="sender">Sender</param>
        private void updateSortCheckboxes(string sortorder, string sender)
        {
            if (sortorder == "name")
            {
                byNameToolStripMenuItem1.CheckState = CheckState.Checked;
                byChannelToolStripMenuItem1.CheckState = CheckState.Unchecked;
                byGroupToolStripMenuItem1.CheckState = CheckState.Unchecked;
            }

            if (sortorder == "channel")
            {
                byChannelToolStripMenuItem1.CheckState = CheckState.Checked;
                byNameToolStripMenuItem1.CheckState = CheckState.Unchecked;
                byGroupToolStripMenuItem1.CheckState = CheckState.Unchecked;
            }

            if (sortorder == "group")
            {
                byGroupToolStripMenuItem1.CheckState = CheckState.Checked;
                byNameToolStripMenuItem1.CheckState = CheckState.Unchecked;
                byChannelToolStripMenuItem1.CheckState = CheckState.Unchecked;
            }
        }

        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex == -1)
            {
                // header was pressed and sortings changed - reset index
                //manage sortings
                return;
            }

            if (Properties.Settings.Default.MouseSetChannel == 1)
            {

                if (e.Button == MouseButtons.Right && e.RowIndex > 0 && e.ColumnIndex > 0)
                {
                    try
                    {
                        dataGridView1.Rows[e.RowIndex].Selected = true;
                    }
                    catch { }
                }

                if (e.Button == MouseButtons.Left)
                    table_ENTER("DATAGRID");
            }
        }

        /// <summary>
        /// Sort all node in treeview by names
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void namesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.AllSortBy = "names";
            populateTreeView();
            treeView1.Nodes[1].Expand();
        }

        /// <summary>
        /// Sort All node in treeView by numbers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void numbersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.AllSortBy = "numbers";
            populateTreeView();
            treeView1.Nodes[1].Expand();
        }

        /// <summary>
        /// Sort favourites in treeview by names.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void namesToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.FavSort = "names";
            populateTreeView();
            treeView1.Nodes[0].Expand();
        }

        /// <summary>
        /// Sort groups in treeview by numbers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void numbersToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.FavSort = "numbers";
            populateTreeView();
            treeView1.Nodes[0].Expand();
        }

        /// <summary>
        /// Sort groups in treeview by names
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void namesToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            sortTreeViewGroups("names");
        }

        /// <summary>
        /// Sort groups in treeview by numbers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void numbersToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            sortTreeViewGroups("numbers");
        }

        /// <summary>
        /// Filter All node in treeView by audio handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void audiodd_MouseDown(object sender, MouseEventArgs e)
        {
            //audio filter in All item was clicked;
            audiosort = ((ToolStripMenuItem)sender).Name;
            filterToolStripMenuItem.DropDown.Hide();
            contextMenuStrip5.Close();
            populateTreeView();
            treeView1.Nodes[1].Expand();
        }

        private void sortTreeViewGroups(string srt)
        {
            int index = -1;
            if (treeView1.SelectedNode != null)
            {
                if (treeView1.SelectedNode.Level == 0)
                    index = treeView1.SelectedNode.Index;
                else if (treeView1.SelectedNode.Level == 1)
                    index = treeView1.SelectedNode.Parent.Index;
            }
            Properties.Settings.Default.GroupSort = srt;
            populateTreeView();
            treeView1.Nodes[index].Expand();
            if (index != -1)
                treeView1.Nodes[index].Expand();
        }

        /// <summary>
        ///Find ip from channel number
        /// </summary>
        /// <param name="ch">Channel number</param>
        public void chantoip(int ch)
        {
            numpad.Stop();
            // ensure that dataview is not filtered
            if (dvchan.RowFilter != rowfilter)
                dvchan.RowFilter = rowfilter;
            int index = dvchan.Find(ch);
            if (index != -1)
            {
                string _ip = (string)dvchan[index][0];
                string _name = (string)dvchan[index][2];
                string _group = (string)dvchan[index][3];
                int _channel = (int)dvchan[index][1];
                bool _skip = (bool)dvchan[index][6];
                bool _locked = (bool)dvchan[index][8];
                ChannelData cd = new ChannelData(_ip, _name, _channel, "@All", _locked, _skip);

                if (pictureBox1.InvokeRequired)
                    pictureBox1.Invoke(new changeChannelFromTimer(setChannel), cd, "NUMPAD");
                else
                    setChannel(cd, "NUMPAD");
            }
        }

        /// <summary>
        ///Returns a list of unique groups
        /// </summary>
        private void getUniqueGroupsList()
        {
            NodeList.Clear();
            NodeList.Add("@Fav");
            NodeList.Add("@All");
            foreach (DataRowView drw in dvcgrp)
            {
                string[] subgroups = drw[3].ToString().Split(',');
                foreach (string group in subgroups)
                {
                    if (!NodeList.Contains(group) && group != "")
                        NodeList.Add(group);
                }
            }
            NodeList.Sort();
        }

        /// <summary>
        ///Returns a list of unique audio names
        /// </summary>
        private void getUniqueAudioList()
        {
            AudioList.Clear();
            foreach (DataRowView drw in dvcaudio)
            {
                string audio = drw[4].ToString().Split(",".ToCharArray())[0];
                if (audio != "" && !AudioList.Contains(audio))
                    AudioList.Add(audio);
            }
        }

        private string extractFirstGroup(string grp)
        {
            string[] splt = grp.Split(',');
            return splt[0];
        }

        void TimerSurf_Tick(object sender, EventArgs e)
        {
            chUpDown("Up");
        }

        #endregion


        #region Vlc related 

        /// <summary>
        /// Start / stop recording
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void recordNowF7ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //start recording
            if (recordNowF7ToolStripMenuItem.CheckState == CheckState.Checked)
                recordnow(1, curcd.Ip, curcd.Name);

            //stop recording
            if (recordNowF7ToolStripMenuItem.CheckState == CheckState.Unchecked)
                recordnow(0, curcd.Ip, curcd.Name);
        }

        /// <summary>
        /// Add list of audio tracks to audio menu
        /// </summary>
        private void dynamicAudioTracksMenu(List<TrackGui> tracks)
        {
            foreach (TrackGui tr in tracks)
            {
                ToolStripMenuItem item = new ToolStripMenuItem();
                item.Text = tr.Name;
                item.Tag = tr;
                item.Click += new EventHandler(aitem_Click);
                audioToolStripMenuItem.DropDown.Items.Add(item);
            }
        }

        /// <summary>
        /// Add list of available subtitles to subtitle menu
        /// </summary>
        private void dynamicSubsMenu(List<TrackGui> tracks)
        {
            //subtitlesToolStripMenuItem
            foreach (TrackGui tr in tracks)
            {
                ToolStripMenuItem item = new ToolStripMenuItem();
                item.Text = tr.Name;
                item.Tag = tr;
                item.Click += new EventHandler(sitem_Click);
                subtitlesToolStripMenuItem.DropDown.Items.Add(item);
            }
        }

        /// <summary>
        ///Audio selected from menu handler
        /// </summary>
        void aitem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            uncheckDynAudioItems();
            item.CheckState = CheckState.Checked;
            TrackGui tr = (TrackGui)item.Tag;
            setAudioTrack(tr.Num);
        }

        /// <summary>
        ///Subtitle selected from menu handler
        /// </summary>
        void sitem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            uncheckDynSubitems();
            item.CheckState = CheckState.Checked;
            TrackGui tr = (TrackGui)item.Tag;
            setSubtitles(tr.Num, tr.Name);
        }

        /// <summary>
        /// Check checkbox of current audio track in menu
        /// </summary>
        private void updateSelectedAudioTrack(int id)
        {
            uncheckDynAudioItems();
            int curid = 0;
            curid = getCurrentAudioTrackId();
            foreach (ToolStripMenuItem item in audioToolStripMenuItem.DropDown.Items)
            {
                if (((TrackGui)item.Tag).Id == id)
                {
                    item.CheckState = CheckState.Checked;
                    break;
                }
            }
        }

        /// <summary>
        /// Check checkbox of current subtitle in menu.
        /// </summary>
        private void checkSelectedSubtitle(int id)
        {
            uncheckDynSubitems();
            int curid = 0;
            curid = getCurrentSubsId();

            foreach (ToolStripMenuItem item in subtitlesToolStripMenuItem.DropDown.Items)
            {
                if (((TrackGui)item.Tag).Id == id)
                {
                    item.CheckState = CheckState.Checked;
                    break;
                }
            }
        }

        /// <summary>
        /// Clear subtitle and audio tracks menus.
        /// </summary>
        private void clearDynamicMenus()
        {
            audioToolStripMenuItem.DropDown.Items.Clear();
            subtitlesToolStripMenuItem.DropDown.Items.Clear();
        }

        private void uncheckDynAudioItems()
        {
            foreach (ToolStripMenuItem item in audioToolStripMenuItem.DropDown.Items)
            {
                if (item.CheckState == CheckState.Checked)
                    item.CheckState = CheckState.Unchecked;
            }
        }

        private void uncheckDynSubitems()
        {
            foreach (ToolStripMenuItem item in subtitlesToolStripMenuItem.DropDown.Items)
            {
                if (item.CheckState == CheckState.Checked)
                    item.CheckState = CheckState.Unchecked;
            }
        }

        /// <summary>
        ///Show/hide PIP window
        /// </summary>
        private void toggleSinglePIP()
        {
            if (pip_last_instance == null || pip_last_instance.IsDisposed)
            {
                VlcNewWindowForm newplayer = new VlcNewWindowForm(curcd, this);
                newplayer.Show();
            }
            else
            {
                pip_last_instance.exit();
            }
        }

        /// <summary>
        ///Show/hide PIP window (when selected from channelTable)
        /// </summary>
        private void toggleSinglePIPfromTable()
        {
            try
            {
                string ip = (string)dataGridView1.SelectedRows[0].Cells[0].Value;
                string name = (string)dataGridView1.SelectedRows[0].Cells[2].Value;
                string group = (string)dataGridView1.SelectedRows[0].Cells[3].Value;
                int num = (int)dataGridView1.SelectedRows[0].Cells[1].Value;
                bool skip = (bool)dataGridView1.SelectedRows[0].Cells[6].Value;
                bool locked = (bool)dataGridView1.SelectedRows[0].Cells[8].Value;
                string tag = (string)dataGridView1.Columns[2].HeaderCell.Tag;
                ChannelData cd = new ChannelData(ip, name, num, tag, locked, skip);
                if (locked)
                {
                    if (!passwordAlert())
                        return;
                }

                if (pip_last_instance == null || pip_last_instance.IsDisposed)
                {
                    VlcNewWindowForm newplayer = new VlcNewWindowForm(cd, this);
                    newplayer.Show();
                }
                else
                {
                    pip_last_instance.exit();
                    if (pip_last_instance == null || pip_last_instance.IsDisposed)
                    {
                        VlcNewWindowForm newplayer = new VlcNewWindowForm(cd, this);
                        newplayer.Show();
                    }
                }

                dataGridView1.Focus();
            }
            catch { }
        }
        
        /// <summary>
        ///Update recordNow checkboxes
        /// </summary>
        private void recNow()
        {
            if (recordNowF7ToolStripMenuItem.CheckState == CheckState.Unchecked)
            {
                recordnow(1, curcd.Ip, curcd.Name);
                recordNowF7ToolStripMenuItem.CheckState = CheckState.Checked;
            }
            else
            {
                recordnow(0, curcd.Ip, curcd.Name);
                recordNowF7ToolStripMenuItem.CheckState = CheckState.Unchecked;
            }
        }

        /// <summary>
        /// Volume up
        /// </summary>
        private void volumeUp()
        {
            string line = "";
            volume = Math.Min(10, volume + 1);
            for (int i = 0; i < volume; i++)
            {
                line = line + "l";
            }
            volOSD(line);
            vlcVolUp();
        }

        /// <summary>
        /// Volume down
        /// </summary>
        private void volumeDown()
        {
            string line = "";
            volume = Math.Max(0, volume - 1);
            for (int i = 0; i < volume; i++)
            {
                line = line + "l";
            }

            if (line.Length == 0)
                line = ".";
            volOSD(line);
            vlcVolDown();
        }

        /// <summary>
        ///Deinterlace mode button clicked
        ///</summary>
        private void deinterlaceToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.VideoDeinterlaceEnabled)
            {
                deinterlaceToolStripMenuItem1.CheckState = CheckState.Unchecked;
                Properties.Settings.Default.VideoDeinterlaceEnabled = false;
                setDeinterlace(false);
            }
            else
            {
                deinterlaceToolStripMenuItem1.CheckState = CheckState.Checked;
                Properties.Settings.Default.VideoDeinterlaceEnabled = true;
                setDeinterlace(true);
            }
        }

        /// <summary>
        ///Cycle through aspect ratios
        /// </summary>
        private void cycleAr()
        {
            car++;
            if (car > (int)Ar.AR_16_9)
            {
                car = (int)Ar.AR_AUTO;
            }

            if (car == (int)Ar.AR_AUTO)
            {
                setAr("default");
                notifyOSD("Orig");
            }
            if (car == (int)Ar.AR_34)
            {
                setAr("4:3");
                notifyOSD("4:3");
            }
            if (car == (int)Ar.AR_14_9)
            {
                setAr("14:9");
                notifyOSD("14:9");
            }
            if (car == (int)Ar.AR_16_10)
            {
                setAr("16:10");
                notifyOSD("16:10");
            }
            if (car == (int)Ar.AR_16_9)
            {
                setAr("16:9");
                notifyOSD("16:9");
            }
        }

        /// <summary>
        ///Uncheck all ar checkboxes
        /// </summary>
        private void uncheckAr()
        {
            defaultToolStripMenuItem.Checked = false;
            toolStripMenuItem5.Checked = false;
            toolStripMenuItem4.Checked = false;
            toolStripMenuItem6.Checked = false;
            toolStripMenuItem7.Checked = false;
        }

        /// <summary>
        ///Update Ar checkboxes
        /// </summary>
        private void arGuiUpdate(string ar)
        {
            if (ar == "default")
            {
                defaultToolStripMenuItem.Checked = true;
                toolStripStatusGeneralInfo.Text = "";
            }
            else if (ar == "4:3")
            {
                toolStripMenuItem5.Checked = true;
                toolStripStatusGeneralInfo.Text = curar;
            }
            else if (ar == "16:9")
            {
                toolStripMenuItem4.Checked = true;
                toolStripStatusGeneralInfo.Text = curar;
            }
            else if (ar == "14:9")
            {
                toolStripStatusGeneralInfo.Text = curar;
                toolStripMenuItem6.Checked = true;
            }
            else if (ar == "16:10")
            {
                toolStripStatusGeneralInfo.Text = curar;
                toolStripMenuItem7.Checked = true;
            }
        }

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            vlcpause();
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            vlcStop();
        }

        private void takeSnapshotSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            takeSnapshot();
        }
        
        /// <summary>
        /// Play selected channel(datagridview) in new window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void showInNewWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string ip = (string)dataGridView1.SelectedRows[0].Cells[0].Value;
            string name = (string)dataGridView1.SelectedRows[0].Cells[2].Value;
            string group = (string)dataGridView1.SelectedRows[0].Cells[3].Value;
            int channel = (int)dataGridView1.SelectedRows[0].Cells[1].Value;
            bool locked = (bool)dataGridView1.SelectedRows[0].Cells[8].Value;
            bool skip = (bool)dataGridView1.SelectedRows[0].Cells[6].Value;
            string tag = (string)dataGridView1.Columns[2].HeaderCell.Tag;
            ChannelData cd = new ChannelData(ip, name, channel, tag, locked, skip);

            if ((bool)dataGridView1.SelectedRows[0].Cells[8].Value)
            {
                if (!passwordAlert())
                    return;
            }
            VlcNewWindowForm newplayer = new VlcNewWindowForm(cd, this);
            newplayer.Show();
        }

        private void showOnDesktopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toggleSinglePIPfromTable();
        }

        private void showInNewWindowToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            //show in new window from side bar

            ChannelData chandata = (ChannelData)treeView1.SelectedNode.Tag;
            if (chandata.Locked)
            {
                if (!passwordAlert())
                    return;
            }
            VlcNewWindowForm newplayer = new VlcNewWindowForm(chandata, this);
            newplayer.Show();
        }

        private void showInWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChannelData chandata = (ChannelData)treeView1.SelectedNode.Tag;

            if (chandata.Locked)
            {
                if (!passwordAlert())
                    return;
            }

            if (pip_last_instance == null || pip_last_instance.IsDisposed)
            {
                VlcNewWindowForm newplayer = new VlcNewWindowForm(chandata, this);
                newplayer.Show();
            }
            else
            {
                pip_last_instance.exit();
                if (pip_last_instance == null || pip_last_instance.IsDisposed)
                {
                    VlcNewWindowForm newplayer = new VlcNewWindowForm(chandata, this);
                    newplayer.Show();
                }
            }
        }

        private void pIPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toggleSinglePIP();
        }
        
        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            setAr("16:9");
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            setAr("16:9");
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            setAr("4:3");
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            setAr("4:3");
        }

        private void defaultToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            setAr("default");
        }

        private void defaultToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setAr("default");
        }

        private void toolStripMenuItem12_Click(object sender, EventArgs e)
        {
            setAr("14:9");
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            setAr("14:9");
        }

        private void toolStripMenuItem13_Click(object sender, EventArgs e)
        {
            setAr("16:10");
        }

        private void toolStripMenuItem7_Click(object sender, EventArgs e)
        {
            setAr("16:10");
        }

        #endregion


        #region Picture dimensions,position,control(temporary workaround for zoom)

        /// <summary>
        ///Set picture dimensions - position and offset
        ///</summary>
        private void pictureDimensions()
        {
            if (splitContainer1.Panel1.Height == 0 || splitContainer1.Panel1.Width == 0)
                return;

            int displayHeight = splitContainer1.Panel1.Height;
            int displayWidth = splitContainer1.Panel1.Width;
            float offsetHorizontal = 0.0f;
            float offsetVertical = 0.0f;
            float newHeight = displayHeight;
            float newWidth = displayWidth;

            //1. Opengl zoom workaround (direct3d is properly modified)
            if (VoutModule == "OpenGL" && displayHeight >0 && displayWidth >0)
            {
                // get picturebox ar
                float ar = (float)displayWidth / (float)displayHeight;
                // zoom
                newHeight = (float)displayHeight * curSettings.Zoom;
                newWidth = newHeight * ar;
                offsetHorizontal = (displayWidth - newWidth) / 2.0f;
                offsetVertical = (displayHeight - newHeight) / 2.0f;
            }

            // 2 correct vertical position 
            if (VoutModule != "Direct3d")
                offsetVertical = offsetVertical - curSettings.VertOffset;

            // 3. set dimensions
            if (VoutModule == "OpenGL")
            {
                pictureBox1.Location = new Point((int)offsetHorizontal, (int)Math.Round(offsetVertical));
                pictureBox1.Height = (int)Math.Round(newHeight);
                pictureBox1.Width = (int)Math.Round(newWidth);
            }
            else
            { 
                pictureBox1.Location = new Point(0, (int)Math.Round(offsetVertical));
                pictureBox1.Height = displayHeight;
                pictureBox1.Width = displayWidth;
            }

            // Applay mask
            // panel2-up, panel3-down // 
            if (curSettings.Mask == 1.0f || curSettings.Mask == 1.0f)
            {
                if (panel2.Visible)
                    panel2.Visible = false; ;
                if (panel3.Visible)
                    panel3.Visible = false;
            }
            else
            {
                // get display width and set height
                float upHeight = ((float)displayHeight - ((float)displayWidth / curSettings.Mask)) / 2.0f;
                float downHeight = upHeight;

                int up = Math.Max(0, (int)Math.Round(upHeight) - curSettings.VertOffset);
                int down = Math.Max(0, (int)Math.Round(downHeight) + curSettings.VertOffset);

                panel2.Location = new Point(0, 0);
                panel2.Width = (int)displayWidth;
                panel2.Height = up;

                panel3.Location = new Point(0, displayHeight - down);
                panel3.Width = displayWidth;
                panel3.Height = down;

                if (!panel2.Visible)
                    panel2.Visible = true;
                if (!panel3.Visible)
                    panel3.Visible = true;
            }
        }

        private void resetPictDim()
        {
            curSettings.Mask = 1.0f;
            curSettings.Zoom = 1.0f;
            curSettings.VertOffset = 0;

            cmask = 0;
            czoom = 0;
            uncheckZoom();
            uncheckMask();
            selectionOSD(MLmessages.Reset + ": OK");
            originalToolStripMenuItem.CheckState = CheckState.Checked;
            noCropToolStripMenuItem4.CheckState = CheckState.Checked;
            toolStripStatusGeneralInfo.Text = "";
            vlcSetZoom(1.0f);
            vlcMovePicture(0);
            pictureDimensions();
        }

        private void movePictUpDown(bool positive)
        {
            // hide main osd
            if (osdshown)
            {
                OsdHideWindow();
                osdshown = false;
            }

            if (positive)
                curSettings.VertOffset = curSettings.VertOffset + 4;
            else
                curSettings.VertOffset = curSettings.VertOffset - 4;

            selectionOSD(MLmessages.Position + ": " + curSettings.VertOffset.ToString());
            vlcMovePicture(curSettings.VertOffset);
        }

        private void cycleMask(bool positive)
        {
            // hide previous osd ???
            if (osdshown)
            {
                OsdHideWindow();
                osdshown = false;
            }

            if (positive)
                cmask++;
            else
                cmask--;

            if (cmask > (int)Mask.CROP_CS)
                cmask = (int)Mask.CROP_NOMASK;
            if (cmask < 0)
                cmask = (int)Mask.CROP_NOMASK;

            if (cmask == (int)Mask.CROP_NOMASK)
                setMask(1.0f, 1.0f, true);

            if (cmask == (int)Mask.CROP_34)
                setMask(4.0f, 3.0f, true);

            if (cmask == (int)Mask.CROP_1_37)
                setMask(48.0f, 35.0f, true);

            if (cmask == (int)Mask.CROP_14_9)
                setMask(14.0f, 9.0f, true);

            if (cmask == (int)Mask.CROP_VISTA1)
                setMask(5.0f, 3.0f, true);

            if (cmask == (int)Mask.CROP_16_9)
                setMask(16.0f, 9.0f, true);

            if (cmask == (int)Mask.CROP_16_9_1)
                setMask(180.0f, 100.0f, true);

            if (cmask == (int)Mask.CROP_VISTA2)
                setMask(185.0f, 100.0f, true);

            if (cmask == (int)Mask.CROP_CS)
                setMask(235.0f, 100.0f, true);
        }

        private void cycleZoom(bool positive)
        {
            // hide previous osd ???
            if (osdshown)
            {
                OsdHideWindow();
                osdshown = false;
            }

            if (positive)
                czoom++;
            else
                czoom--;

            if (czoom > (int)Zoom.ZOOM_2_0)
                czoom = (int)Zoom.ZOOM_NOZOOM;

            if (czoom < 0)
                czoom = (int)Zoom.ZOOM_NOZOOM;

            string szoom = "";
            float fzoom = 1.0f;
            if (czoom == (int)Zoom.ZOOM_NOZOOM)
                fzoom = 1.0f;

            if (czoom == (int)Zoom.ZOOM_1_0_5)
            {
                fzoom = 1.05f;
                szoom = fzoom.ToString("0.00");
            }

            if (czoom == (int)Zoom.ZOOM_1_1)
                fzoom = 1.1f;

            if (czoom == (int)Zoom.ZOOM_1_2)
                fzoom = 1.2f;

            if (czoom == (int)Zoom.ZOOM_1_3)
                fzoom = 1.3f;

            if (czoom == (int)Zoom.ZOOM_1_4)
                fzoom = 1.4f;

            if (czoom == (int)Zoom.ZOOM_1_5)
                fzoom = 1.5f;

            if (czoom == (int)Zoom.ZOOM_1_6)
                fzoom = 1.6f;

            if (czoom == (int)Zoom.ZOOM_1_7)
                fzoom = 1.7f;

            if (czoom == (int)Zoom.ZOOM_1_8)
                fzoom = 1.8f;

            if (czoom == (int)Zoom.ZOOM_1_9)
                fzoom = 1.9f;

            if (czoom == (int)Zoom.ZOOM_2_0)
                fzoom = 2.0f;

            if (szoom == "")
                szoom = fzoom.ToString("0.0");

            curSettings.Zoom = fzoom;
            selectionOSD("Zoom: " + szoom);
            zoomGuiUpdate(null, fzoom, true);
            pictureDimensions();
            vlcSetZoom(fzoom);
        }

        /// <summary>
        /// Picturebox (splitcontainer1-panel1) resize event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
        {
            if (splitContainer1.Panel1.Height == 0 || splitContainer1.Panel1.Width == 0)
                return;

            pictureDimensions();
            ttxLabelSize();
            recLabelSize();    
        }

        /// <summary>
        /// Adjust ttx label size and position
        /// </summary>
        private void ttxLabelSize()
        {
            float font = Math.Max(10.0f, (float)splitContainer1.Panel1.Width / 50.0f) * Properties.Settings.Default.OsdSizeFactor; ;

            label2.Font = new Font(label2.Font.FontFamily, font, label2.Font.Style);
            label2.Location = new Point(Math.Max((pictureBox1.Width - label2.Width) - (int)font - Properties.Settings.Default.EpgPopUpXOffset, 1), Properties.Settings.Default.OSDYposition);

        }

        /// <summary>
        /// Adjust rec label size and position
        /// </summary>
        private void recLabelSize()
        {
            float font = Math.Max(10.0f, (float)splitContainer1.Panel1.Width / 50.0f) * Properties.Settings.Default.OsdSizeFactor;

            label1.Font = new Font(label1.Font.FontFamily, font, label1.Font.Style);
            label1.Location = new Point(Math.Max((pictureBox1.Width - label1.Width) - (int)font - Properties.Settings.Default.EpgPopUpXOffset, 1) - label2.Width, Properties.Settings.Default.OSDYposition);
        }

        private void uncheckZoom()
        {
            originalToolStripMenuItem.CheckState = CheckState.Unchecked;
            toolStripMenuItem2.CheckState = CheckState.Unchecked;
            toolStripMenuItem3.CheckState = CheckState.Unchecked;
            toolStripMenuItem8.CheckState = CheckState.Unchecked;
            toolStripMenuItem9.CheckState = CheckState.Unchecked;
            toolStripMenuItem12.CheckState = CheckState.Unchecked;
            toolStripMenuItem13.CheckState = CheckState.Unchecked;
            toolStripMenuItem16.CheckState = CheckState.Unchecked;
            toolStripMenuItem17.CheckState = CheckState.Unchecked;
            toolStripMenuItem18.CheckState = CheckState.Unchecked;
            toolStripMenuItem19.CheckState = CheckState.Unchecked;
            toolStripMenuItem20.CheckState = CheckState.Unchecked;
        }

        private void cyclePictSettings()
        {
            // hide main osd
            if (osdshown)
            {
                OsdHideWindow();
                osdshown = false;
            }

            cPictSet++;

            if (cPictSet > (int)PictSet.RESET)
                cPictSet = (int)PictSet.EXIT;

            // show osd
            if (cPictSet == (int)PictSet.ZOOM)
                selectionOSD("Zoom: " + curSettings.Zoom.ToString("0.0"));

            if (cPictSet == (int)PictSet.POSITION)
                selectionOSD(MLmessages.Position + ": " + curSettings.VertOffset.ToString());

            if (cPictSet == (int)PictSet.MASK)
                selectionOSD(MLmessages.Mask + ": " + curSettings.Mask.ToString("0.0"));

            if (cPictSet == (int)PictSet.RESET)
                selectionOSD(MLmessages.Reset);

            if (cPictSet == (int)PictSet.EXIT)
                OsdHideWindow();
        }

        /// <summary>
        ///Update mask related gui
        /// </summary>
        /// <param name="mask">Mask ratio</param>
        private void maskGuiUpdate(float r)
        {
            r = (float)Math.Round(r, 2);

            string guitext = r.ToString("0.00");
            if (r == 1.00f)
            {
                noCropToolStripMenuItem4.CheckState = CheckState.Checked; //strip
                cmask = (int)Mask.CROP_NOMASK;
                guitext = "Original";
            }

            if (r == 1.33f)
            {
                toolStripMenuItem10.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_34;
            }

            if (r == 1.56f)
            {
                toolStripMenuItem15.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_14_9;
            }

            if (r == 1.37f)
            {
                toolStripMenuItem14.CheckState = CheckState.Checked;
                guitext = "1.37:1";
                cmask = (int)Mask.CROP_1_37;
            }

            if (r == 1.78f)
            {
                toolStripMenuItem11.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_16_9;
            }

            if (r == 1.67f)
            {
                vistavision2ToolStripMenuItem1.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_VISTA1;
            }

            if (r == 1.80f)
            {
                guitext = "~16:9";
                cmask = (int)Mask.CROP_16_9_1;
            }

            if (r == 1.85f)
            {
                vistavisionToolStripMenuItem.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_VISTA2;
            }
            if (r == 2.35f)
            {
                cinemascopeToolStripMenuItem1.CheckState = CheckState.Checked;
                cmask = (int)Mask.CROP_CS;
            }
            //toolStripStatusLabel2.Text = guitext;
        }

        /// <summary>
        ///Uncheck all mask checkboxes
        /// </summary>
        private void uncheckMask()
        {
            noCropToolStripMenuItem4.CheckState = CheckState.Unchecked;
            toolStripMenuItem10.CheckState = CheckState.Unchecked;
            toolStripMenuItem11.CheckState = CheckState.Unchecked;
            vistavisionToolStripMenuItem.CheckState = CheckState.Unchecked;
            vistavision2ToolStripMenuItem1.CheckState = CheckState.Unchecked;
            cinemascopeToolStripMenuItem1.CheckState = CheckState.Unchecked;
            toolStripMenuItem14.CheckState = CheckState.Unchecked;
            toolStripMenuItem15.CheckState = CheckState.Unchecked;
        }

        private void originalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.0f, true);
        }
       
        private void toolStripMenuItem2_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.05f, true);
        }

        private void toolStripMenuItem3_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.1f, true);
        }

        private void toolStripMenuItem8_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.2f, true);
        }

        private void toolStripMenuItem9_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.3f, true);
        }

        private void toolStripMenuItem12_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.4f, true);
        }

        private void toolStripMenuItem13_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.5f, true);
        }

        private void toolStripMenuItem16_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.6f, true);
        }

        private void toolStripMenuItem17_Click_1(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.7f, true);
        }

        private void toolStripMenuItem18_Click(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.8f, true);
        }

        private void toolStripMenuItem19_Click(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 1.9f, true);
        }

        private void toolStripMenuItem20_Click(object sender, EventArgs e)
        {
            zoomGuiUpdate((ToolStripMenuItem)sender, 2.0f, true);
        }

        private void zoomGuiUpdate(ToolStripMenuItem cb, float r, bool uncheck)
        {
            if (uncheck)
                uncheckZoom();

            curSettings.Zoom = r;

            r = (float)Math.Round(r, 2);

            if (cb != null)
            {
                cb.CheckState = CheckState.Checked;
                vlcSetZoom(r);
                toolStripStatusGeneralInfo.Text = "";
            }
            else
            {
                string guitext = r.ToString("0.00");

                if (r == 1.00f)
                {
                    originalToolStripMenuItem.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_NOZOOM;
                }

                if (r == 1.05f)
                {
                    toolStripMenuItem2.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_0_5;

                }
                if (r == 1.10f)
                {
                    toolStripMenuItem3.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_1;

                }
                if (r == 1.20f)
                {
                    toolStripMenuItem8.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_2;
                }

                if (r == 1.30f)
                {
                    toolStripMenuItem9.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_3;
                }

                if (r == 1.40f)
                {
                    toolStripMenuItem12.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_4;
                }

                if (r == 1.50f)
                {
                    toolStripMenuItem13.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_5;
                }

                if (r == 1.60f)
                {
                    toolStripMenuItem16.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_6;
                }
                if (r == 1.70f)
                {
                    toolStripMenuItem17.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_7;
                }
                if (r == 1.80f)
                {
                    toolStripMenuItem18.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_8;
                }
                if (r == 1.90f)
                {
                    toolStripMenuItem19.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_1_9;
                }
                if (r == 2.00f)
                {
                    toolStripMenuItem20.CheckState = CheckState.Checked; //strip
                    czoom = (int)Zoom.ZOOM_2_0;
                }

                if (r == 1.00f)
                    toolStripStatusGeneralInfo.Text = "";
                else
                    toolStripStatusGeneralInfo.Text = "Zoom: " + guitext;
            }

        }

        private void noCropToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            setMask(1.0f, 1.0f, false);
        }

        private void toolStripMenuItem8_Click(object sender, EventArgs e)
        {
            setMask(4.0f, 3.0f, false);
        }

        private void toolStripMenuItem9_Click(object sender, EventArgs e)
        {
            setMask(16.0f, 9.0f, false);
        }

        private void vistavision2ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            setMask(5.0f, 3.0f, false);
        }

        private void vistVisionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setMask(185.0f, 100.0f, false); //vistavision 
        }

        private void cinemascopeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setMask(235.0f, 100.0f, false); //cinemascope
        }

        private void noCropToolStripMenuItem4_Click(object sender, EventArgs e)
        {
            setMask(1.0f, 1.0f, false);
        }

        private void toolStripMenuItem10_Click(object sender, EventArgs e)
        {
            setMask(4.0f, 3.0f, false);
        }

        private void toolStripMenuItem11_Click(object sender, EventArgs e)
        {
            setMask(16.0f, 9.0f, false);
        }

        private void vistavision2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setMask(5.0f, 3.0f, false);
        }

        private void vistavisionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setMask(185.0f, 100.0f, false);
        }

        private void cinemascopeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            setMask(235.0f, 100.0f, false);
        }

        private void toolStripMenuItem16_Click(object sender, EventArgs e)
        {
            setMask(48.0f, 35.0f, false);
        }

        private void toolStripMenuItem17_Click(object sender, EventArgs e)
        {
            setMask(14.0f, 9.0f, false);
        }

        private void toolStripMenuItem14_Click(object sender, EventArgs e)
        {
            setMask(48.0f, 35.0f, false);
        }

        private void toolStripMenuItem15_Click(object sender, EventArgs e)
        {
            setMask(14.0f, 9.0f, false);
        }

        #endregion


        #region Add to Scheduler

        /// <summary>
        /// // Add an item to sheduler from epg in listview.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void recordToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DateTime now = DateTime.Now;
            string namepostfix;
            DateTime start;
            DateTime stop = DateTime.Now;

            if (listView1.SelectedItems.Count > 0)
            {
                start = (DateTime)((object[])listView1.SelectedItems[0].Tag)[0];
                namepostfix = (string)((object[])listView1.SelectedItems[0].Tag)[4];
                string recip = (string)((object[])listView1.SelectedItems[0].Tag)[2];
                string recname = (string)((object[])listView1.SelectedItems[0].Tag)[3];

                if (listView1.Items.Count - 1 >= listView1.SelectedIndices[0] + 1 && listView1.Items[listView1.SelectedIndices[0] + 1].Text.Length > 2)
                {
                    stop = (DateTime)((object[])listView1.Items[listView1.SelectedIndices[0] + 1].Tag)[0];
                }
                else
                {
                    EnterStopTime form = new EnterStopTime(start);
                    form.ShowDialog();
                    stop = form.getStopDate;
                }

                //offsets
                start = start.AddMinutes(Properties.Settings.Default.RecStartOffset);
                stop = stop.AddMinutes(Properties.Settings.Default.RecStopOffset);

                if (start.Subtract(now).TotalMinutes < 0 && stop.Subtract(now).TotalMinutes > 0)
                    start = now.AddSeconds(2);

                RecTableContainer.dt.Tables[0].Rows.Add(start, stop, recname, stop.Subtract(start).TotalMinutes, "", recip, "pending", namepostfix);
                StandBy.loadTimerJobs();
            }
        }
        
        /// <summary>
        /// Add selected node in treeView to scheduler
        /// </summary>
        /// <param name="minutes">Recording time in minutes</param>
        private void treeViewAddToSched(double minutes)
        {
            string namepostfix = "";
            string recchan = "";  // channel name
            string recip = "";

            ChannelData chandata = (ChannelData)treeView1.SelectedNode.Tag;

            recchan = chandata.Name;
            recip = chandata.Ip;
            bool locked = chandata.Locked;
            if (locked)
            {
                if (!passwordAlert())
                    return;
            }
            DateTime start = DateTime.Now.AddSeconds(2);
            DateTime stop = start.AddMinutes(minutes);
            RecTableContainer.dt.Tables[0].Rows.Add(start, stop, recchan, stop.Subtract(start).TotalMinutes, "", recip, "pending", namepostfix);
            StandBy.loadTimerJobs();
        }

        private void lengthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            addToRecordingSchedulerToolStripMenuItem.ShowDropDown();
        }

        private void minToolStripMenuItem_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(10);
        }

        private void minToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(30);
        }

        private void hourToolStripMenuItem_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(60);
        }
        
        private void hour30MinToolStripMenuItem_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(90);
        }

        private void hoursToolStripMenuItem_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(120);
        }

        private void hours30MinToolStripMenuItem_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(150);
        }

        private void hoursToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            treeViewAddToSched(180);
        }

        #endregion


        #region Control

        private Point distanceFormMouse;
        private Point hiddenMousePos;
        public Point HiddemMousePos
        {
            get { return hiddenMousePos; }
        }

        /// <summary>
        ///Key pressed event handler - when picturebox has focus
        /// </summary>
        private void pictureBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            //RIGHT (vol down)
            if (e.KeyCode== Properties.Settings.Default.KeyRIGHT)
                volumeUp();

            //LEFT (vol up)
            if (e.KeyCode == Properties.Settings.Default.KeyLEFT)
                volumeDown();

            // UP (ch up)
            if (e.KeyData == Properties.Settings.Default.KeyUP)
            {
                if (cPictSet == (int)PictSet.ZOOM)
                    cycleZoom(true);
                else if (cPictSet == (int)PictSet.MASK)
                    cycleMask(true);
                else if (cPictSet == (int)PictSet.POSITION)
                    movePictUpDown(true);
                else if (cPictSet == (int)PictSet.RESET)
                    resetPictDim();
                else
                    chUpDown("Up");
            }

            // DOWN (ch down)
            if (e.KeyData == Properties.Settings.Default.KeyDOWN)
            {
                if (cPictSet == (int)PictSet.ZOOM)
                    cycleZoom(false);
                else if (cPictSet == (int)PictSet.MASK)
                    cycleMask(false);
                else if (cPictSet == (int)PictSet.POSITION)
                    movePictUpDown(false);
                else if (cPictSet == (int)PictSet.RESET)
                    resetPictDim();
                else
                    chUpDown("Down");
            }

            // F7(rec now)
            if (e.KeyData == Properties.Settings.Default.KeyRec)
                recNow();

            // escape from full screen normalview
            if (e.KeyData == Properties.Settings.Default.KeyNormalView)
                setNormalMode();

            //minimal mode
            if (e.KeyData == Properties.Settings.Default.KeyMinimal)
                setWindowMode(false);

            // osd status
            if (e.KeyData == Properties.Settings.Default.KeyOSD)
                toggleOsd();

            //full screen
            if (e.KeyData == Properties.Settings.Default.KeyFullScreen)
                setFullScreenMode();

            //channel table
            if (e.KeyData == Properties.Settings.Default.KeyTable)
                showchannelTable();

            //mute
            if (e.KeyData == Properties.Settings.Default.KeyMute)
                toggleMute();

            //keypad
            if (e.KeyData == Keys.NumPad0 || e.KeyCode == Keys.D0)
                numpadInput(0);

            if (e.KeyData == Keys.NumPad1 || e.KeyCode == Keys.D1)
                numpadInput(1);

            if (e.KeyData == Keys.NumPad2 || e.KeyCode == Keys.D2)
                numpadInput(2);

            if (e.KeyData == Keys.NumPad3 || e.KeyCode == Keys.D3)
                numpadInput(3);

            if (e.KeyData == Keys.NumPad4 || e.KeyCode == Keys.D4)
                numpadInput(4);

            if (e.KeyData == Keys.NumPad5 || e.KeyCode == Keys.D5)
                numpadInput(5);

            if (e.KeyData == Keys.NumPad6 || e.KeyCode == Keys.D6)
                numpadInput(6);

            if (e.KeyData == Keys.NumPad7 || e.KeyCode == Keys.D7)
                numpadInput(7);

            if (e.KeyData == Keys.NumPad8 || e.KeyCode == Keys.D8)
                numpadInput(8);

            if (e.KeyData == Keys.NumPad9 || e.KeyCode == Keys.D9)
                numpadInput(9);

            //pause
            if (e.KeyData == Properties.Settings.Default.KeyPause)
                vlcpause();

            //faster (timeshift)
            if (e.KeyData == Properties.Settings.Default.KeyFaster)
                vlcfaster();

            //slower (timeshift)
            if (e.KeyData == Properties.Settings.Default.KeySlower)
                vlcslower();

            // teletext
            if (e.KeyData == Properties.Settings.Default.KeyTeletext)
                toggleTTX();

            //snapshot 
            if (e.KeyData == Properties.Settings.Default.KeySnapshot)
                takeSnapshot();

            //recall
            if (e.KeyData == Properties.Settings.Default.KeyRecall)
                prevChan();

            //cycle ar
            if (e.KeyData == Properties.Settings.Default.KeyAR)
                cycleAr();

            //cycle crop
            if (e.KeyData == Properties.Settings.Default.KeyPictSet)
                cyclePictSettings();

            // audio languages
            if (e.KeyData == Properties.Settings.Default.KeyLanguage)
                cycleAudioLanguages();

            // subtitles
            if (e.KeyData == Properties.Settings.Default.KeySubtitles)
                cycleSubtitles();

            //dailyepg
            if (e.KeyData == Properties.Settings.Default.KeyEPG)
                showDailyEpg();

            //PIP
            if (e.KeyData == Properties.Settings.Default.KeyPip)
                toggleSinglePIP();

            //minimize 
            if (e.KeyData == Properties.Settings.Default.KeyMinimize)
                this.WindowState = FormWindowState.Minimized;

            // exit
            if (e.KeyData == Properties.Settings.Default.KeyQuit)
                this.Close();

            // to tray
            if (e.KeyData == Properties.Settings.Default.KeyToTray)
            {
                StandBy.toTray = true;
                this.Close();
            }

            // TEST key
            if (e.KeyData == Keys.F9)
            {
                //test();
                TestFunction();
            }

            // Surf key
            if (e.KeyData == Properties.Settings.Default.KeySurf)
            {
                if (TimerSurf.Enabled)
                {
                    TimerSurf.Stop();
                    notifyOSD("Stop");
                    toolStripStatusGeneralInfo.Text = "Stop";
                }
                else
                {
                    TimerSurf.Start();
                    notifyOSD("Start");
                    toolStripStatusGeneralInfo.Text = "Start";
                }
            }
        }

        /// <summary>
        ///Overriden window procedure
        ///Custom message handler for remote control
        /// </summary>
        protected override void WndProc(ref Message m)
        {
            //REMOTE CONTROLL HANDLER
            if (m.Msg == 0x8888)
            {
                // vol down
                if (m.WParam == new IntPtr(11))
                    volumeDown();

                // vol up
                else if (m.WParam == new IntPtr(12))
                    volumeUp();

                // ch up
                else if (m.WParam == new IntPtr(13))
                    chUpDown("Up");

                // ch down
                else if (m.WParam == new IntPtr(14))
                    chUpDown("Down");

                // F7(rec now)
                else if (m.WParam == new IntPtr(15))
                    recNow();

                // escape from focused controls
                else if (m.WParam == new IntPtr(16))
                {
                    if (daily.Visible)
                    {
                        daily.Visible = false;
                    }
                    else if (panel1.Visible)
                    {
                        panel1.Visible = false;
                    }
                }

                //minimal mode
                else if (m.WParam == new IntPtr(17))
                    setWindowMode(false);

                // osd status
                else if (m.WParam == new IntPtr(18))
                    toggleOsd();

                //full screen
                else if (m.WParam == new IntPtr(19))
                    setFullScreenMode();

                //channel table
                else if (m.WParam == new IntPtr(20))
                    showchannelTable();

                //mute
                else if (m.WParam == new IntPtr(21))
                    toggleMute();

                //numbers
                else if (m.WParam == new IntPtr(0))
                    numpadInput(0);
                else if (m.WParam == new IntPtr(1))
                    numpadInput(1);
                else if (m.WParam == new IntPtr(2))
                    numpadInput(2);
                else if (m.WParam == new IntPtr(3))
                    numpadInput(3);
                else if (m.WParam == new IntPtr(4))
                    numpadInput(4);
                else if (m.WParam == new IntPtr(5))
                    numpadInput(5);
                else if (m.WParam == new IntPtr(6))
                    numpadInput(6);
                else if (m.WParam == new IntPtr(7))
                    numpadInput(7);
                else if (m.WParam == new IntPtr(8))
                    numpadInput(8);
                else if (m.WParam == new IntPtr(9))
                    numpadInput(9);

                //pause
                else if (m.WParam == new IntPtr(22))
                    vlcpause();

                //faster (timeshift)
                else if (m.WParam == new IntPtr(23))
                    vlcfaster();

                //slower (timeshift)
                else if (m.WParam == new IntPtr(24))
                    vlcslower();

                //snapshot 
                else if (m.WParam == new IntPtr(25))
                    takeSnapshot();

                //recall
                else if (m.WParam == new IntPtr(26))
                    prevChan();

                //cycle ar
                else if (m.WParam == new IntPtr(27))
                    cycleAr();

                //cycle crop
                else if (m.WParam == new IntPtr(28))
                    cyclePictSettings();

                // UP
                else if (m.WParam == new IntPtr(100))
                {
                    if (!daily.Visible && !panel1.Visible)
                    {   
                        // pict settings
                        if (cPictSet == (int)PictSet.ZOOM)
                            cycleZoom(true);
                        else if (cPictSet == (int)PictSet.MASK)
                            cycleMask(true);
                        else if (cPictSet == (int)PictSet.POSITION)
                            movePictUpDown(true);
                        else if (cPictSet == (int)PictSet.RESET)
                            resetPictDim();
                    }
                    // channel table
                    else if (!daily.Visible && panel1.Visible)
                    {
                        table_UP();
                    }
                    // epg
                    else if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.table_UP));
                        else
                            daily.table_UP();
                    }
                }

                 // DOWN
                else if (m.WParam == new IntPtr(101))
                {
                    if (!daily.Visible && !panel1.Visible)
                    {    
                        // pict settings
                        if (cPictSet != 0)
                        {
                            if (cPictSet == (int)PictSet.ZOOM)
                                cycleZoom(false);
                            else if (cPictSet == (int)PictSet.MASK)
                                cycleMask(false);
                            else if (cPictSet == (int)PictSet.POSITION)
                                movePictUpDown(false);
                            else if (cPictSet == (int)PictSet.RESET)
                                resetPictDim();
                        }
                      
                    }
                    // channel table
                    else if (!daily.Visible && panel1.Visible)
                    {
                        table_DOWN();
                    }
                    // epg
                    else if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.table_DOWN));
                        else
                            daily.table_DOWN();
                   }
                }

                 // LEFT
                else if (m.WParam == new IntPtr(102))
                {
                    if (!daily.Visible && !panel1.Visible)
                    {
                        // nothing
                    }
                    // channel table
                    else if (!daily.Visible && panel1.Visible)
                    {
                        table_LEFT();
                    }
                    // epg
                    else if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateEpgDetNext(daily.setNextChannel), false, false, true);
                        else
                            daily.setNextChannel(false, false, true);
                    }
                }
                // RIGHT
                else if (m.WParam == new IntPtr(103))
                {
                    if (!daily.Visible && !panel1.Visible)
                    {
                        // nothing
                    }
                    // channel table
                    else if (!daily.Visible && panel1.Visible)
                    {
                        table_RIGHT();
                    }
                    // epg
                    else if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateEpgDetNext(daily.setNextChannel), true, false, true);
                        else
                            daily.setNextChannel(true, false, true);
                    }
                }

                 // ENTER
                else if (m.WParam == new IntPtr(104))
                {
                    if (!daily.Visible && !panel1.Visible)
                    {
                        showchannelTable();
                    }
                    // channel table
                    else if (!daily.Visible && panel1.Visible)
                        table_ENTER("DATAGRID");

                    // epg
                    else if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.changeChannel));
                        else
                            daily.changeChannel();
                    }
                }

               // PIP
                else if (m.WParam == new IntPtr(29))
                {
                    if (!daily.Visible && !panel1.Visible)
                        toggleSinglePIP();
                    else if (!daily.Visible && panel1.Visible)
                        toggleSinglePIPfromTable();
                }

                // epg scroll up
                else if (m.WParam == new IntPtr(30))
                {
                    if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.scroll_UP));
                        else
                            daily.scroll_UP();
                    }
                }

                // epg scroll down
                else if (m.WParam == new IntPtr(31))
                {
                    if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.scroll_DOWN));
                        else
                            daily.scroll_DOWN();
                    }
                }

                // epg zoom in
                else if (m.WParam == new IntPtr(32))
                {
                    if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.zoomIn));
                        else
                            daily.zoomIn();
                    }
                }

               // epg zoom out
                else if (m.WParam == new IntPtr(33))
                {
                    if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.zoomOut));
                        else
                            daily.zoomOut();
                    }
                }

                 // epg START
                else if (m.WParam == new IntPtr(34))
                {
                    if (!Properties.Settings.Default.FullScreen)
                        setFullScreenMode();
                    showDailyEpg();
                }

               // teletext
                else if (m.WParam == new IntPtr(35))
                {
                    toggleTTX();
                }

                // epg background
                else if (m.WParam == new IntPtr(36))
                {
                    if (daily.IsHandleCreated && daily.Visible)
                    {
                        if (daily.InvokeRequired)
                            daily.Invoke(new delegateNoParams(daily.toggleTransparent));
                        else
                            daily.toggleTransparent();
                    }
                }

                // exit
                else if (m.WParam == new IntPtr(99))
                {
                    this.Close();
                }

               // vlc stop
                else if (m.WParam == new IntPtr(37))
                {
                    vlcStop();
                }

                // adio languages
                else if (m.WParam == new IntPtr(38))
                {
                    cycleAudioLanguages();
                }

                // subtitles
                else if (m.WParam == new IntPtr(39))
                {
                    cycleSubtitles();
                }

                m.Result = new IntPtr(0);
                // base.WndProc(ref m);
                //m.Result = new IntPtr(0);
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        /// <summary>
        /// Open preferences window in modal mode. Reconfiguration is needed when window is closed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PreferencesForm pref = new PreferencesForm(this, path, dataGridView1);
            pref.ShowDialog();

            // SOME RECONFIGURATION NEEDED AFTER
            channelManagementReconfiguration();

            //epg timer
            if (Properties.Settings.Default.EnableEpgplugin)
                TimerEpgListview.Start();
            else
                TimerEpgListview.Stop();

            //datagridview colors
            dgwColors();
            //sidebar
            sidebarcolors();
            //statustrip + interface statistics timer
            getInterfaceStatistics();
            statustripInfo();

            //unicast / multicast
            if (Properties.Settings.Default.Multicast)
            {
                normalToolStripMenuItem.CheckState = CheckState.Checked;
                uToolStripMenuItem.CheckState = CheckState.Unchecked;
            }
            else
            {
                normalToolStripMenuItem.CheckState = CheckState.Unchecked;
                uToolStripMenuItem.CheckState = CheckState.Checked;
            }
            
            //update vout module
            VoutModule = Properties.Settings.Default.VideoOutV3;

            //Lock parental control
            PasswordEncription.Unlocked = false;
        }

        /// <summary>
        /// Recording scheduler form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void localToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //show recording schedule window
            if (!Globals.RecTableAllreadyOpenned)
            {
                RecForm schedule = new RecForm(path);
                Globals.RecTableAllreadyOpenned = true;
                schedule.ShowDialog();
                Globals.RecTableAllreadyOpenned = false;
            }
        }

        /// <summary>
        ///Show "Check for new channels" form.
        ///</summary>
        private void checkForNewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (panel1.Visible)
                panel1.Visible = false;
            CheckForNewChannels nc = new CheckForNewChannels(this);
            nc.Show();
        }

        /// <summary>
        /// Open remux/recode form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void convertToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemuxForm rf = new RemuxForm();
            rf.Show();
        }

        /// <summary>
        ///Multicast mode selected
        /// </summary>
        private void normalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!recordNowF7ToolStripMenuItem.Enabled)
                recordNowF7ToolStripMenuItem.Enabled = true;

            if (!showInNewWindowToolStripMenuItem.Enabled)
                showInNewWindowToolStripMenuItem.Enabled = true;

            if (!showInNewWindowToolStripMenuItem1.Enabled)
                showInNewWindowToolStripMenuItem1.Enabled = true;
            if (!pIPToolStripMenuItem.Enabled)
                pIPToolStripMenuItem.Enabled = true;

            normalToolStripMenuItem.CheckState = CheckState.Checked;
            uToolStripMenuItem.CheckState = CheckState.Unchecked;
            vlcStop();
            Properties.Settings.Default.Multicast = true;

            if (Properties.Settings.Default.UnicastServer == "vlc")
                vlmClearChannel(false);
            else if (Properties.Settings.Default.UnicastServer == "udprelay")
                udprClearChannel(false);

            setChannel(curcd, "MAIN");
        }

        /// <summary>
        ///Unicast mode selected
        /// </summary>
        private void uToolStripMenuItem_Click(object sender, EventArgs e)
        {
            recordNowF7ToolStripMenuItem.Enabled = false;
            showInNewWindowToolStripMenuItem.Enabled = false;
            showInNewWindowToolStripMenuItem1.Enabled = false;
            pIPToolStripMenuItem.Enabled = false;

            uToolStripMenuItem.CheckState = CheckState.Checked;
            normalToolStripMenuItem.CheckState = CheckState.Unchecked;
            UnicastConntest contest = new UnicastConntest();

            vlcStop();
            Properties.Settings.Default.Multicast = false;
            setChannel(curcd, "MAIN");
        }

        /// <summary>
        /// Import channel list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (panel1.Visible)
                panel1.Visible = false; ;
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.Filter = "atvlist, m3u, xls, csv (*.atvlist;*.m3u;*.xls;*.csv)|*.ATVLIST;*.M3U;*.XLS;*.CSV";
            openFileDialog1.FileName = "";
            openFileDialog1.InitialDirectory = path + @"\import\";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                Thread import;
                import = new Thread(new ThreadStart(importInNewThread));
                import.IsBackground = true;
                import.Start();
            }
        }

        private void importInNewThread()
        {
            PreserveFavourites pf = new PreserveFavourites(Globals.UserAppPath);
            pf.saveBeforeImporting();
            StandBy.fillChannelTable(openFileDialog1.FileName);
            pf.restoreAfterImporting();
            // thread pool
            this.Invoke(new delegateNoParams(channelManagementReconfiguration));

            ChannelTable.menu.Tables["Menu"].WriteXml(Globals.UserAppPath + @"\..\channellist.xml");
        }

        /// <summary>
        ///Minimal view toggle
        /// </summary>
        /// <param name="init">Init</param>
        private void setWindowMode(bool init)
        {
            // detect if we went to window mode from fs
            if (Properties.Settings.Default.FullScreen)
            {
                if (Globals.RecInstanceCount == 0 && !Properties.Settings.Default.ScreenSaver)
                {
                    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
                }
                if (!Properties.Settings.Default.ScreenSaver)
                    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, true, 0, 0);

                if (allwaysOnTopToolStripMenuItem.CheckState == CheckState.Checked)
                    this.TopMost = true;

                //hide osdfs
                if (panel4.Visible)
                    showEpgPopup(false);
                if (daily.Visible)
                    daily.Visible = false;
            }

            if (!Properties.Settings.Default.WindowMode || init)
            {
                this.WindowState = FormWindowState.Normal;
                menuStrip1.Hide();
                statusStrip1.Hide();
                this.Text = string.Empty;
                this.ControlBox = false;
                
                this.FormBorderStyle = FormBorderStyle.Sizable;
                Properties.Settings.Default.WindowMode = true;
                Properties.Settings.Default.FullScreen = false;
                windowToolStripMenuItem.CheckState = CheckState.Checked;
                fullscreenToolStripMenuItem.CheckState = CheckState.Unchecked;
                fullScreenToolStripMenuItem1.CheckState = CheckState.Unchecked;
                if (treeToolStripMenuItem.CheckState == CheckState.Checked)
                    splitContainer1.Panel2Collapsed = false;
                else
                    splitContainer1.Panel2Collapsed = true;
                prevmode = "min";
            }
            else // go to normal
            {
                normalModeSettings();
                prevmode = "";
            }
            pictureDimensions();
        }

        /// <summary>
        ///Full screen toggle
        /// </summary>
        private void setFullScreenMode()
        {
            if (!Properties.Settings.Default.FullScreen)
            {
                //start the timer
                TimerMouseHide.Start();
                if (Globals.RecInstanceCount == 0 && !Properties.Settings.Default.ScreenSaver)
                {
                    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED);
                }
                if (!Properties.Settings.Default.ScreenSaver)
                    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, false, 0, 0);

                fullscreenToolStripMenuItem.CheckState = CheckState.Checked;
                fullScreenToolStripMenuItem1.CheckState = CheckState.Checked;
                windowToolStripMenuItem.CheckState = CheckState.Unchecked;

                this.FormBorderStyle = FormBorderStyle.None;

                splitContainer1.Panel2Collapsed = true;
                if (menuStrip1.Visible)
                    menuStrip1.Visible = false;
                if (statusStrip1.Visible)
                    statusStrip1.Visible = false;

                Properties.Settings.Default.FullScreen = true;
                Properties.Settings.Default.WindowMode = false;

                this.WindowState = FormWindowState.Maximized;

                if (pipInstances > 0)
                    this.TopMost = false;
            }
            else
            {
                if (allwaysOnTopToolStripMenuItem.CheckState == CheckState.Checked)
                    this.TopMost = true;

                //hide osdfs
                if (panel4.Visible)
                    showEpgPopup(false);

                //hide osddetails
                if (daily.Visible)
                    daily.Visible = false;

                //go to prev mode
                if (prevmode == "min")
                {
                    setWindowMode(false);
                }
                else//go to normal
                {
                    if (Globals.RecInstanceCount == 0 && !Properties.Settings.Default.ScreenSaver)
                    {
                        SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
                    }
                    if (!Properties.Settings.Default.ScreenSaver)
                        SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, true, 0, 0);

                    normalModeSettings();
                    this.FormBorderStyle = FormBorderStyle.Sizable;
                    prevmode = "";
                }
            }
            pictureDimensions();
        }

        /// <summary>
        ///Normal mode
        /// </summary>
        private void setNormalMode()
        {
            if (panel4.Visible)
                showEpgPopup(false);
            if (daily.Visible)
                daily.Visible = false;

            if (allwaysOnTopToolStripMenuItem.CheckState == CheckState.Checked)
                this.TopMost = true;

            if (Properties.Settings.Default.FullScreen)
            {
                setFullScreenMode();
            }
            if (Properties.Settings.Default.WindowMode)
            {
                setWindowMode(false);
            }
            pictureDimensions();
        }

        private void normalModeSettings()
        {
            menuStrip1.Show();
            if (Properties.Settings.Default.StatusBarView)
                statusStrip1.Show();
            this.ControlBox = true;
            this.Text = "MulticastTV";
            this.WindowState = FormWindowState.Normal;
            windowToolStripMenuItem.CheckState = CheckState.Unchecked;
            fullscreenToolStripMenuItem.CheckState = CheckState.Unchecked;
            fullScreenToolStripMenuItem1.CheckState = CheckState.Unchecked;
            if (treeToolStripMenuItem.CheckState == CheckState.Checked)
                splitContainer1.Panel2Collapsed = false;
            else
                splitContainer1.Panel2Collapsed = true;
            Properties.Settings.Default.WindowMode = false;
            Properties.Settings.Default.FullScreen = false;
        }

        /// <summary>
        /// Show channel selection table
        /// TODO: In window mode channel table should not overlap with video. 
        /// Picturebox should be pushed to the right and resized.
        /// Don't forget to change form resize handler.
        /// </summary>
        private void showchannelTable()
        {
            if (panel1.Visible)//Hide
            {
                panel1.Visible = false;
                pictureBox1.Focus();
            }
            else//Show
            {
                if (!Properties.Settings.Default.FullScreen)
                {
                    panel1.Width = 200;
                    // calculate normal table container dimensions
                    if (Properties.Settings.Default.WindowMode)
                        panel1.Location = new Point(25, 40 + (this.Height / 24));
                    else
                        panel1.Location = new Point(25, 60 + (this.Height / 24));

                    if (panel1.Width > this.Width - splitContainer1.Panel2.Width)
                        this.Size = new Size(this.Height, panel1.Width + 10);

                    if (370 >= pictureBox1.Height - 100)
                    {
                        if (Properties.Settings.Default.WindowMode)
                            panel1.Height = panel1.Height - (panel1.Height - pictureBox1.Height) - 70;
                        else
                            panel1.Height = panel1.Height - (panel1.Height - pictureBox1.Height) - 100;
                    }
                    else
                        panel1.Height = 370;
                    dataGridView1.Height = panel1.Height;
                }
                else
                {
                    calculateFSTableContainerDimensions();
                }

                // show container
                panel1.Visible = true;
                panel1.BringToFront();

                // ensure that current selected channel is  visible when we show table
                //updateTableWithCurChn(curcd.Ip, "MAIN");

                // configure table metrics
                changeTableFonts();
                dataGridView1.Columns[0].Visible = false;
                dataGridView1.Focus();
            }
        }

        private void toggleAllwaysOnTop()
        {
            if (!Properties.Settings.Default.FullScreen)
            {
                if (!this.TopMost)
                {
                    this.TopMost = true;
                    allwaysOnTopToolStripMenuItem.CheckState = CheckState.Checked;
                    Properties.Settings.Default.AllwaysOnTop = true;
                }
                else
                {
                    // In full screen only PIP has to be TopMost.
                    this.TopMost = false;
                    allwaysOnTopToolStripMenuItem.CheckState = CheckState.Unchecked;
                    Properties.Settings.Default.AllwaysOnTop = false;
                }
            }
        }

        private void setAllwaysOnTop(bool set)
        {
            if (set)
            {
                allwaysOnTopToolStripMenuItem.CheckState = CheckState.Checked;
                Properties.Settings.Default.AllwaysOnTop = true;
                this.TopMost = true;
            }
            else
            {
                allwaysOnTopToolStripMenuItem.CheckState = CheckState.Unchecked;
                Properties.Settings.Default.AllwaysOnTop = false;
                this.TopMost = false;
            }
        }

        public void ttxNuminput(int number)
        {
            if (ttxnumpad.Length < 3)
            {
                ttxnumpad.Append(number.ToString());
                label2.Text = ttxnumpad.ToString();
            }
            if (ttxnumpad.Length == 3)
            {
                setTeletext(Int32.Parse(ttxnumpad.ToString()));
                ttxnumpad.Length = 0;
            }
        }

        private void table_PIP()
        {
            toggleSinglePIPfromTable();
        }

        /// <summary>
        ///Show/hide channel selection treeview
        /// </summary>
        private void toggleTree()
        {
            if (treeToolStripMenuItem.CheckState == CheckState.Checked)
            {
                splitContainer1.Panel2Collapsed = true;
                treeToolStripMenuItem.CheckState = CheckState.Unchecked;
            }
            else
            {
                splitContainer1.Panel2Collapsed = false;
                treeToolStripMenuItem.CheckState = CheckState.Checked;
            }
        }

        /// <summary>
        /// Mouse move over picturebox event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (Properties.Settings.Default.WindowMode && mouseleft)
                this.Location = new Point(MousePosition.X - distanceFormMouse.X, MousePosition.Y - distanceFormMouse.Y);

            if (!mouseshown && (Math.Abs(hiddenMousePos.X - Cursor.Position.X) > 2 || Math.Abs(hiddenMousePos.Y - Cursor.Position.Y) > 2))
            {
                Cursor.Show();
                mouseshown = true;
                TimerMouseHide.Stop();
                TimerMouseHide.Start();
            }

            // this wont work on secondary screen
            Point screen = Cursor.Position;

            if (!panel1.Visible && Properties.Settings.Default.FullScreen && screen.X == 0 && (screen.Y > panel1.Location.Y && screen.Y < panel1.Location.Y + panel1.Height))
                showchannelTable();

            if (Properties.Settings.Default.FullScreen && screen.Y == this.Height - 1 && epg != null && !panel4.Visible)
                showEpgOsd();
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            if (!dataGridView1.Focused && !daily.Visible)
                pictureBox1.Focus();
        }

        // TODO: SIMPLIFY THIS !!!!!
        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (!mouseleft)
            {
                if (!Properties.Settings.Default.MouseForVolume)
                {
                    if (e.Delta > 16)
                    {
                        if (!Properties.Settings.Default.MouseSwap)
                            chUpDown("Up");
                        else
                            chUpDown("Down");
                    }

                    if (e.Delta < -16)
                    {
                        if (!Properties.Settings.Default.MouseSwap)
                            chUpDown("Down");
                        else
                            chUpDown("Up");
                    }
                }
                else
                {
                    //volume up
                    if (e.Delta > 16)
                        volumeUp();
                    //volume down
                    else if (e.Delta < -16)
                        volumeDown();
                }
            }
            else
            {
                if (!Properties.Settings.Default.MouseForVolume)
                {
                    //volume up
                    if (e.Delta > 16)
                        volumeUp();
                    //volume down
                    else if (e.Delta < -16)
                        volumeDown();
                }
                else
                {
                    if (e.Delta > 16)
                    {
                        if (!Properties.Settings.Default.MouseSwap)
                            chUpDown("Up");
                        else
                            chUpDown("Down");
                    }

                    if (e.Delta < -16)
                    {
                        if (!Properties.Settings.Default.MouseSwap)
                            chUpDown("Down");
                        else
                            chUpDown("Up");
                    }
                }
            }
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            //ensure mouse visibility
            if (!mouseshown)
            {
                Cursor.Show();
                mouseshown = true;
                TimerMouseHide.Stop();
                TimerMouseHide.Start();
            }

            if (e.Button == MouseButtons.Left && e.Clicks == 2)
            {
                setFullScreenMode();
                return;
            }

            distanceFormMouse = new Point(MousePosition.X - this.Location.X, MousePosition.Y - this.Location.Y);
            pictureBox1.Focus();

            if (e.Button == MouseButtons.Left)
            {
                mouseleft = true;
                if (panel1.Visible)
                    panel1.Visible = false;
            }

            if (e.Button == MouseButtons.Middle)
                prevChan();
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                mouseleft = false;
        }

        /// <summary>
        /// Tree node mouse click handler.
        /// If single click for chan. change is defined, it changes channel, otherwise it just updates epg.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Level == 0)
                return;

            //treeView1 single mouseclick
            if (e.Button == MouseButtons.Right)
                treeView1.SelectedNode = e.Node;

            //update epg
            if (e.Button == MouseButtons.Left && Properties.Settings.Default.MouseSetChannel == 2)
            {
                if (e.Button == MouseButtons.Left && Properties.Settings.Default.EnableEpgplugin)
                {
                    ChannelData chandata = (ChannelData)e.Node.Tag;
                    string channame = chandata.Name;
                    string ip = chandata.Ip;
                    bool locked = chandata.Locked;

                    if (doubleClickFromTreeElapsed)
                        clearListview();

                    if (!locked)
                    {
                        if (epg != null)
                        {
                            epg.start(channame, new epgResult(ip, channame, "main_listview")); //!!!
                            TimerEpgTreeview.Stop();
                            TimerEpgTreeview.Start();
                            doubleClickFromTreeElapsed = false;
                        }
                    }
                }
            }

            //change channel
            if (Properties.Settings.Default.MouseSetChannel == 1)
            {
                if (e.Button == MouseButtons.Left)
                {
                    ChannelData cd = (ChannelData)e.Node.Tag;
                    setChannel(cd, "TREEVIEW");

                }
            }
        }

        /// <summary>
        /// Tree Node mouse double click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Level == 0)
                return;

            //treeView1  mouse double event handler - set channel
            if (Properties.Settings.Default.MouseSetChannel == 2)
            {
                ChannelData chandata = (ChannelData)e.Node.Tag;
                setChannel(chandata, "TREEVIEW");
            }
        }

        /// <summary>
        /// Treeview key down handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (treeView1.SelectedNode.Level == 0)
                return;

            if (e.KeyData == Keys.Enter)
            {
                setChannel((ChannelData)treeView1.SelectedNode.Tag, "TREEVIEW");
            }
            else if (e.KeyData == Keys.Back)
                textBox1.Focus();
        }

        /// <summary>
        /// Search textbox key down handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter || e.KeyData == Keys.Up || e.KeyData == Keys.Down)
            {
                // select first item from treeview
                TreeNode temp = treeView1.Nodes[1];
                if (temp.Nodes.Count > 0)
                {
                    treeView1.SelectedNode = temp.Nodes[0];
                    treeView1.Select();
                }
                e.Handled = true;
            }
        }

        /// <summary>
        /// Search textbox -text changed handler.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            filterTreeView();
        }
        
        /// <summary>
        /// Channel table key down handler.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            // datagrid (channel table) key events

            if (e.KeyData == Keys.Enter && panel1.Visible)
            {
                table_ENTER("DATAGRID");
                e.Handled = true;
            }

            // sortings
            if (e.KeyData == Keys.Right)
                table_RIGHT();

            if (e.KeyData == Keys.Left)
                table_LEFT();

            if (e.KeyData == Keys.Down)
            {
                table_DOWN();
                e.Handled = true;
            }

            if (e.KeyData == Keys.Up)
            {
                table_UP();
                e.Handled = true;
            }

            if (e.KeyData == Properties.Settings.Default.KeyPip)
                table_PIP();

            if (e.KeyData == Properties.Settings.Default.KeyTable && panel1.Visible)
            {
                panel1.Visible = false;
                pictureBox1.Focus();
            }
        }
        
        private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            //show menustrip in datagridview1 (for "show in new window")
            if (e.Button == MouseButtons.Right && e.RowIndex > 0)
            {
                dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[1];
                contextMenuStrip3.Show(Cursor.Position);
            }
        }

        private void dataGridView1_MouseWheel(object sender, MouseEventArgs e)
        {
            DataGridView.HitTestInfo ht = dataGridView1.HitTest(e.X, e.Y);
            if (ht.RowIndex == -1 && ht.ColumnIndex == 2)
            {
                if (e.Delta > 16)
                    table_LEFT();
                else if (e.Delta < -16)
                    table_RIGHT();
            }
            else
            {

                int count = dataGridView1.Rows.Count;
                if (count > 0)
                {
                    if (e.Delta > 16)
                        dataGridView1.FirstDisplayedScrollingRowIndex = Math.Max(dataGridView1.FirstDisplayedScrollingRowIndex - 3, 0);
                    else if (e.Delta < -16)
                        dataGridView1.FirstDisplayedScrollingRowIndex = Math.Min(dataGridView1.FirstDisplayedScrollingRowIndex + 3, count);
                }
            }
        }

        private void fullScreenToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            setFullScreenMode();
        }

        private void fullscreenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setFullScreenMode();
        }

        private void windowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setWindowMode(false);
        }

        private void window1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setWindowMode(false);
        }

        private void statusbarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.StatusBarView)
            {
                statusStrip1.Hide();
                statusbarToolStripMenuItem.CheckState = CheckState.Unchecked;
                Properties.Settings.Default.StatusBarView = false;
            }
            else
            {
                statusStrip1.Show();
                statusbarToolStripMenuItem.CheckState = CheckState.Checked;
                Properties.Settings.Default.StatusBarView = true;
            }
        }

        private void showChannelWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            showchannelTable();
        }
       
        private void allwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toggleAllwaysOnTop();
        }

        private void channelTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            showchannelTable();
        }
        
        private void TimerMouseHide_Tick(Object sender, EventArgs e)
        {
            if (Properties.Settings.Default.FullScreen && mouseshown && !panel1.Visible && !daily.Visible)
            {
                Cursor.Hide();
                hiddenMousePos = Cursor.Position;
                mouseshown = false;
                TimerMouseHide.Stop();
                TimerMouseHide.Start();
            }
        }

        private void tableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            showchannelTable();
        }

        private void treeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toggleTree();
        }

        private void treeView1_MouseEnter(object sender, EventArgs e)
        {
            //focus enter treeview
            treeView1.Focus();
        }

        private void listView1_MouseEnter(object sender, EventArgs e)
        {
            //focus enter listview1
            listView1.Focus();
        }

        private void dataGridView1_MouseEnter(object sender, EventArgs e)
        {
            //focus datagridview1
            dataGridView1.Focus();
        }

        private void contextMenuStrip1_MouseEnter(object sender, EventArgs e)
        {
            TimerMouseHide.Stop();
        }

        private void contextMenuStrip1_MouseLeave(object sender, EventArgs e)
        {
            TimerMouseHide.Start();
        }
        
        private void infoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 about = new AboutBox1();
            about.ShowDialog();
        }

        private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            // show help chm
            if (Properties.Settings.Default.language == "Slovenian")
                Help.ShowHelp(this, path + @"\multicasttv_slo.chm");
            else
                Help.ShowHelp(this, path + @"\multicasttv.chm");
        }

        private void listToolStripMenuItem_Click(object sender, EventArgs e)
        {
            listView1.View = View.List;
            updateAllListviewViews();
        }

        private void tileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //tile
            listView1.View = View.Tile;
            updateAllListviewViews();
        }

        private void largeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //small
            listView1.View = View.LargeIcon;
            updateAllListviewViews();
        }

        private void smallToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //large
            listView1.View = View.SmallIcon;
            updateAllListviewViews();
        }

        /// <summary>
        /// Open rec folder
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void openRecordingDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(Properties.Settings.Default.RecFolder);
        }

        /// <summary>
        /// Show an epg item in external browser.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListView lw = (ListView)sender;
                string href = (string)((object[])(lw.SelectedItems[0].Tag))[1];
                try
                {
                    System.Diagnostics.Process.Start(href);
                }
                catch { }
            }
        }

        private void openInExternalBrowserToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                string href = (string)((object[])(listView1.SelectedItems[0].Tag))[1];
                System.Diagnostics.Process.Start(href);
            }
            catch { }
        }

        /// <summary>
        /// Form resize handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Resize(object sender, EventArgs e)
        {
            if (panel1.Visible && panel1.Width > this.Width)
                this.Size = new Size(this.Height, panel1.Width + 10);
        }

        private void Form1_Move(object sender, EventArgs e)
        {
            if (osdshown)
            {
                OsdHideWindow();
                osdshown = false;
            }
        }

        #endregion


        #region Epg and Osd

        /// <summary>
        ///Enable epg
        /// </summary>
        public void enableEpg()
        {
            if (epg == null && Properties.Settings.Default.EPGPlugin != "")
            {
                epg = new Epg();
                epg.Finished += new Epg.EpgFinishedHandler(epg_Finished);
            }
        }
        
        /// <summary>
        ///Show/hide channel name and show epg pop-up with updated epg data
        /// </summary>
        public void toggleOsd()
        {
            chanOSD(curcd.Name);
            if (Properties.Settings.Default.FullScreen)
                showEpgPopup(true);
        }

        /// <summary>
        ///Show epg pop-up. It also updates data from net or cache.
        ///
        /// </summary>
        public void showEpgOsd()
        {
            if (epg != null)
            {
                if (Properties.Settings.Default.FullScreen && !panel4.Visible)
                    showEpgPopup(true);
            }
        }

        /// <summary>
        ///Show or hide EPG pop-up with data update (cache or net)
        /// </summary>
        /// <param name="show">Show?</param>
        public void showEpgPopup(bool show)
        {
            if (show && Properties.Settings.Default.FullScreen && !fsodshown)
            {
                PopUpShowWindow();
                // update epg
                if (Properties.Settings.Default.EnableEpgplugin)
                {
                    if (epg != null)
                        epg.start(curcd.Name, new epgResult(curcd.Ip, curcd.Name, "main"));
                }
            }
            else
                PopUpHide();
        }

        /// <summary>
        ///Show daily epg form
        /// </summary>
        private void showDailyEpg()
        {
            if (!daily.Visible && Properties.Settings.Default.FullScreen)
            {
                daily.StartPosition = FormStartPosition.Manual;
                daily.Size = this.Size;
                daily.Location = this.Location;
                daily.Show();
            }
            else
                daily.Visible = false;
        }

        /// <summary>
        ///OSD for numpad input
        /// </summary>
        private void chanOSDinput()
        {
            if (!this.Visible)
                return;

            // reset selection osd !!!
            cPictSet = 0;

            int alpha = 80;

            if (Properties.Settings.Default.OSDshow)
            {
                osdshown = true;
                int size = (int)Math.Max(8, (float)this.Height * Properties.Settings.Default.OsdSizeFactor / 24.0f);
                OsdStart(numpadstr.ToString(), "left", new Font("Verdana", size, FontStyle.Bold | FontStyle.Italic), Properties.Settings.Default.OSDcolor, size, alpha, Properties.Settings.Default.OSDTImeout, Properties.Settings.Default.OSDXposition, Properties.Settings.Default.OSDYposition);
            }
        }

        /// <summary>
        ///OSD for aspect and crop ratio info
        /// </summary>
        /// <param name="cropar">Crop/Ar ratio</param>
        private void notifyOSD(string cropar)
        {
            if (!this.Visible)
                return;

            // reset selection osd !!!
            cPictSet = 0;

            int alpha = 90;

            if (!statusStrip1.Visible && Properties.Settings.Default.OSDshow)
            {
                int timeout = Properties.Settings.Default.OSDTImeout;
                if (cropar == MLmessages.Pause)
                    timeout = int.MaxValue;
                osdshown = true;
                int size = (int)Math.Max(8, (float)this.Height * Properties.Settings.Default.OsdSizeFactor / 32.0f);
                if (Properties.Settings.Default.WindowMode || Properties.Settings.Default.FullScreen)
                    OsdStart(cropar, "left", new Font("Verdana", size, FontStyle.Bold | FontStyle.Italic), Properties.Settings.Default.OSDcolor, size, alpha, timeout, Properties.Settings.Default.OSDXposition, Properties.Settings.Default.OSDYposition);
            }
        }

        /// <summary>
        ///OSD for selections (mask, zoom...) - it dooesn't hide
        /// </summary>
        /// <param name="rate">Text</param>
        private void selectionOSD(string rate)
        {
            if (!this.Visible)
                return;

            int alpha = 90;

            if (Properties.Settings.Default.OSDshow)
            {
                int timeout = 0;
                osdshown = true;
                int size = (int)Math.Max(8, (float)this.Height * Properties.Settings.Default.OsdSizeFactor / 32.0f);
                OsdStart(rate, "left", new Font("Verdana", size, FontStyle.Bold | FontStyle.Italic), Properties.Settings.Default.OSDcolor, size, alpha, timeout, Properties.Settings.Default.OSDXposition, Properties.Settings.Default.OSDYposition);
            }
        }

        /// <summary>
        ///OSD for channel name
        /// </summary>
        /// <param name="cname">Channel name</param>
        private void chanOSD(string cname)
        {
            if (!this.Visible)
                return;

            // reset selection osd !!!
            cPictSet = 0;

            int alpha = 90;

            if (!statusStrip1.Visible && Properties.Settings.Default.OSDshow)
            {
                OsdHideWindow();
                osdshown = true;
                int size = (int)Math.Max(8, (float)this.Height * Properties.Settings.Default.OsdSizeFactor / 32.0f);
                if (Properties.Settings.Default.WindowMode || Properties.Settings.Default.FullScreen)
                    OsdStart(cname, "left", new Font("Verdana", size, FontStyle.Bold | FontStyle.Italic), Properties.Settings.Default.OSDcolor, size, alpha, Properties.Settings.Default.OSDTImeout, Properties.Settings.Default.OSDXposition, Properties.Settings.Default.OSDYposition);
            }
        }

        /// <summary>
        ///Osd for volume. One letter "l" means 20%
        /// </summary>
        private void volOSD(string line)
        {
            if (!this.Visible)
                return;

            // reset selection osd !!!
            cPictSet = 0;

            int alpha = 90;

            if (Properties.Settings.Default.OSDshow)
            {
                osdshown = true;
                int size = (int)Math.Max(8, (float)this.Height * Properties.Settings.Default.OsdSizeFactor / 32.0f);
                int width = this.Width;
                Point loc = this.Location;

                OsdStart(line, "right", new Font("Verdana", size, FontStyle.Bold), Properties.Settings.Default.OSDcolor, size, alpha, Properties.Settings.Default.OSDTImeout, Properties.Settings.Default.OSDXposition, Properties.Settings.Default.OSDYposition);
            }
        }
        
        private void panel3_MouseMove(object sender, MouseEventArgs e)
        {
            if (Properties.Settings.Default.FullScreen && e.Y == panel3.Height - 1 && epg != null && !panel4.Visible)
            {
                showEpgOsd();
            }
        }

        private void splitContainer1_Panel1_MouseMove(object sender, MouseEventArgs e)
        {

            if (Properties.Settings.Default.FullScreen && e.Y == splitContainer1.Panel1.Height - 1 && epg != null && !panel4.Visible)
            {
                showEpgOsd();
            }
        }

        /// <summary>
        /// Epg refresh (without data downloading) handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void TimerEpgListview_Tick(object sender, EventArgs e)
        {
            highlightCurrentEpgItem(true, false);
        }

        private void TimerDataGrid_Tick(object sender, EventArgs e)
        {
            TimerEpgTreeview.Stop();
            doubleClickFromTreeElapsed = true;
        }

        private void ePGToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ePGToolStripMenuItem.CheckState == CheckState.Checked)
            {
                ePGToolStripMenuItem.CheckState = CheckState.Unchecked;
                splitContainer2.Panel2Collapsed = true;
            }
            else
            {
                ePGToolStripMenuItem.CheckState = CheckState.Checked;
                splitContainer2.Panel2Collapsed = false;
            }
        }

        private void dailyEpgToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!Properties.Settings.Default.FullScreen)
                setFullScreenMode();
            showDailyEpg();
        }
        
        #endregion
        
        
        #region  Appearance and Metrics

        /// <summary>
        ///Calculate channel table dimensions in full screen mode
        /// </summary>
        private void calculateFSTableContainerDimensions()
        {
            // Prevent overlapping with osd .    
            // Osd size is based of screen height as follows: this.Height / 32;
            panel1.Location = new Point(Properties.Settings.Default.TableXpos, Properties.Settings.Default.TableYpos + Properties.Settings.Default.OSDYposition + this.Height / 32);
            panel1.Width = Properties.Settings.Default.TableWidth;
            panel1.Height = Properties.Settings.Default.TableHeight;
            dataGridView1.Height = panel1.Height;
        }

        /// <summary>
        ///Change table font (size)
        /// </summary>
        private void changeTableFonts()
        {
            // check for font
            if (!Properties.Settings.Default.FullScreen)
            {
                // normal mode
                if (!dataGridView1.DefaultCellStyle.Font.Equals(Properties.Settings.Default.TableFontNORM))
                    dataGridView1.DefaultCellStyle.Font = new Font(Properties.Settings.Default.TableFontNORM, Properties.Settings.Default.TableFontNORM.Style);
            }
            else
            {
                // fullscreen mode
                if (!dataGridView1.DefaultCellStyle.Font.Equals(Properties.Settings.Default.TableFontFS))
                    dataGridView1.DefaultCellStyle.Font = new Font(Properties.Settings.Default.TableFontFS, Properties.Settings.Default.TableFontFS.Style);
            }
            //adjust row height
            dataGridView1.AutoResizeRows();
            preventPartialRows();
        }

        /// <summary>
        ///Prevent partially visible rows in channel table
        /// </summary>
        private void preventPartialRows()
        {
            // get number of visible rows
            int NumOfRows = dataGridView1.DisplayedRowCount(false);

            // get new row height
            int RowHeight;
            if (dataGridView1.Rows.Count > 0)
            {
                RowHeight = dataGridView1.Rows[0].Height;
                // correct table height
                int FullTableHeight = dataGridView1.ColumnHeadersHeight + (NumOfRows * RowHeight);
                dataGridView1.Height = FullTableHeight + 3;
            }
            // resize height
            dataGridView1.Width = panel1.Width;
        }

        private void dgwColors()
        {
            //dataGridView1.colum
            dataGridView1.RowsDefaultCellStyle.BackColor = Properties.Settings.Default.TableBackColor_v2;
            panel1.BackColor = Properties.Settings.Default.TableBackColor_v2;
            dataGridView1.RowsDefaultCellStyle.ForeColor = Properties.Settings.Default.TableTextColor;
            dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Properties.Settings.Default.TableBackColor_v2;
            dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Properties.Settings.Default.TableTextColor;
            dataGridView1.GridColor = Properties.Settings.Default.TableBackColor_v2;
            dataGridView1.BackgroundColor = Properties.Settings.Default.TableBackColor_v2;
        }

        public void sidebarcolors()
        {
            treeView1.BackColor = Properties.Settings.Default.SideBarBackColor;
            treeView1.ForeColor = Properties.Settings.Default.SidebarFontColor;
            treeView1.Font = Properties.Settings.Default.SidebarFont;
            textBox1.BackColor = Properties.Settings.Default.SideBarBackColor;
            textBox1.ForeColor = Properties.Settings.Default.SidebarFontColor;
            splitContainer2.Panel1.BackColor = Properties.Settings.Default.SideBarBackColor;
            splitContainer2.Panel1.ForeColor = Properties.Settings.Default.SidebarFontColor;
            splitContainer2.Panel2.BackColor = Properties.Settings.Default.EPGBackColor;
            //epg background
            listView1.BackColor = Properties.Settings.Default.EPGBackColor;
            listView1.Font = Properties.Settings.Default.EPGFont;
            listView1.ForeColor = Properties.Settings.Default.EPGTextColor;
        }
       
        public void statustripInfo()
        {
            if (!Properties.Settings.Default.ShowStatusStripDetails)
            {
                toolStripStatusLabelName.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusLabelName.AutoSize = true;
                toolStripStatusNetSpeed.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusNetSpeed.Text = "";
                toolStripStatusLabelVideoInfo.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusLabelVideoInfo.Text = "";
                toolStripStatusLabelAudioChannels.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusLabelAudioChannels.Text = "";
                toolStripStatusAudioCount.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusAudioCount.Text = "";
                toolStripStatusSubsCount.BorderSides = ToolStripStatusLabelBorderSides.None;
                toolStripStatusSubsCount.Text = "";
            }
            else
            {
                toolStripStatusLabelName.BorderSides = ToolStripStatusLabelBorderSides.Right;
                toolStripStatusLabelName.AutoSize = false;
                toolStripStatusLabelName.Size = new Size(200, toolStripStatusLabelName.Size.Height);
                toolStripStatusNetSpeed.BorderSides = ToolStripStatusLabelBorderSides.Right;
                toolStripStatusLabelVideoInfo.BorderSides = ToolStripStatusLabelBorderSides.Right;
                toolStripStatusLabelAudioChannels.BorderSides = ToolStripStatusLabelBorderSides.Right;
                toolStripStatusAudioCount.BorderSides = ToolStripStatusLabelBorderSides.Right;
                toolStripStatusSubsCount.BorderSides = ToolStripStatusLabelBorderSides.Right;
            }
        }
       
        #endregion


        #region Other

        private void initNetmeterTimer()
        {
            
            if (TimerNetMonitor != null)
                    TimerNetMonitor.Dispose();
            if (TimerNetMonitorGui != null)
                    TimerNetMonitorGui.Dispose();
            
            if (Properties.Settings.Default.ShowStatusStripDetails)
            {
                TimerNetMonitor = new System.Timers.Timer(1000);
                TimerNetMonitor.Elapsed += new System.Timers.ElapsedEventHandler(TimerNetMonitor_Tick);
                TimerNetMonitor.Start();
                // presenting timer
                TimerNetMonitorGui.Start();
            }
        }

        private void getInterfaceStatistics()
        {
            int parsedindex = -1;
            Int32.TryParse(Globals.interfaceindex, out parsedindex);
            // interface stats
            if (parsedindex != -1)
            {
                Interfaces intf = new Interfaces();
                MulticastAdapter = intf.getAdapter(parsedindex);
                if (MulticastAdapter != null)
                {
                    IPv4InterfaceStatistics ipstat = MulticastAdapter.GetIPv4Statistics();
                    bytesReceived = ipstat.BytesReceived;
                    initNetmeterTimer();
                }
            }
        }
       
        /// <summary>
       /// Parental control
       /// </summary>
       /// <returns></returns>
        private bool passwordAlert()
        {
            if (!mouseshown)
            {
                Cursor.Show();
                mouseshown = true;
                TimerMouseHide.Stop();
                TimerMouseHide.Start();
            }

            bool cont = false;
            // no password is set
            if (PasswordEncription.Password == "" || PasswordEncription.Unlocked)
            {
                // don't ask
                cont = true;
                return cont;
            }

            //180x104
            // calculate position for password window
            Point InputPos = new Point(0, 0);
            InputPos.X = splitContainer1.Panel1.Width / 2 - 90;
            InputPos.Y = splitContainer1.Panel1.Height / 2 - 52;
            InputPos = splitContainer1.Panel1.PointToScreen(InputPos);

            Check ch = new Check(false);
            Password PassCheck = new Password(ch, InputPos);
            if (!PasswordEncription.Unlocked)
            {
                PassCheck.ShowDialog();
            }
            if (ch.correct)
            {
                cont = true;
                PasswordEncription.Unlocked = true;
            }

            return cont;
        }

        /// <summary>
        /// Uncheck all checkboxes in listview1.
        /// </summary>
        private void updateAllListviewViews()
        {
            listToolStripMenuItem.CheckState = CheckState.Unchecked;
            tileToolStripMenuItem.CheckState = CheckState.Unchecked;
            largeToolStripMenuItem.CheckState = CheckState.Unchecked;
            smallToolStripMenuItem.CheckState = CheckState.Unchecked;

            if (listView1.View == View.List)
                listToolStripMenuItem.CheckState = CheckState.Checked;
            if (listView1.View == View.Tile)
                tileToolStripMenuItem.CheckState = CheckState.Checked;
            if (listView1.View == View.LargeIcon)
                largeToolStripMenuItem.CheckState = CheckState.Checked;
            if (listView1.View == View.SmallIcon)
                smallToolStripMenuItem.CheckState = CheckState.Checked;
        }

        /// <summary>
        /// net monitor calculating timer
        /// <summary>
        void TimerNetMonitor_Tick(object source, ElapsedEventArgs e)
        {
            //refresh bandwith info
            IPv4InterfaceStatistics ipstat = MulticastAdapter.GetIPv4Statistics();
            long newbytes = ipstat.BytesReceived;
            speed = (float) Math.Round(((newbytes - bytesReceived)*8) / (1000.0f * 1000.0f) , 1);
            bytesReceived = newbytes;
        }

        /// <summary>
        /// Net monitor presenting timer
        /// <summary>
        void TimerNetMonitorGui_Tick(object sender, EventArgs e)
        {
            toolStripStatusNetSpeed.Text = currentSpeed.ToString("0.0") + " Mb/s";
        }
        
        /// <summary>
        /// Ensures that ttx label is not shown when channel is changed
        /// </summary>
        private void cleatTtxGui()
        {
            label2.Visible = false;
            label2.Text = "TTX";
            teletextMode = false;
            cttx = 0;
        }
        
        private void clearStripMenus()
        {
            toolStripStatusGeneralInfo.Text = "";
            toolStripStatusLabelVideoInfo.Text = "";
            toolStripStatusLabelAudioChannels.Text = "";
            toolStripStatusSubsCount.Text = "";
            toolStripStatusAudioCount.Text = "";
        }

        /// <summary>
        /// Clear listview before we call update
        /// </summary>
        private void clearListview()
        {
            listView1.BeginUpdate();
            listView1.Items.Clear();
            listView1.EndUpdate();
        }

        #endregion


        #region To tray, Closing, Closed, Exit ...

        private void minimizeToTrayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StandBy.toTray = true;
            this.Close();
        }
        
        private void saveFormSettings()
        {
            //save form1 related settings
            if (Properties.Settings.Default.RememberLastSelectedChan)
            {
                Properties.Settings.Default.LastChannelNumber = curcd.Num;
                Properties.Settings.Default.LastNode = curcd.Node;
            }
            else
            {
                Properties.Settings.Default.LastNode = "@All";
            }

            if (fullscreenToolStripMenuItem.CheckState == CheckState.Checked)
                Properties.Settings.Default.FullScreen = true;
            else
                Properties.Settings.Default.FullScreen = false;

            if (!Properties.Settings.Default.FullScreen)
            {
                Properties.Settings.Default.splitter = splitContainer1.SplitterDistance;
                Properties.Settings.Default.splitter2 = splitContainer2.SplitterDistance;
            }

            Properties.Settings.Default.EPGListView = listView1.View;
            if (this.WindowState != FormWindowState.Minimized)
            {
                Properties.Settings.Default.LastPosition = this.Location;
                Properties.Settings.Default.LastSize = this.Size;
            }

            if (!Properties.Settings.Default.FullScreen)
            {
                if (splitContainer1.Panel2Collapsed)
                    Properties.Settings.Default.treeviev = false;
                else
                    Properties.Settings.Default.treeviev = true;

                if (splitContainer2.Panel2Collapsed)
                    Properties.Settings.Default.EPGView = false;
                else
                    Properties.Settings.Default.EPGView = true;

                if (statusStrip1.Visible)
                    Properties.Settings.Default.StatusBarView = true;
                else
                {
                    if (statusbarToolStripMenuItem.CheckState == CheckState.Checked)
                        Properties.Settings.Default.StatusBarView = true;
                    else
                        Properties.Settings.Default.StatusBarView = false;
                }
            }
            Properties.Settings.Default.LastVolume = volume;
            Properties.Settings.Default.LastAr = curar;
        }
        
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool cont = true;
            //check for RecNow
            if (vlc_rec != null)
            {
                this.TopMost = false;
                if (MessageBox.Show(MLmessages.RecAllowAbort + "\n" + MLmessages.RecNowInfo, "", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    e.Cancel = true;
                    cont = false;
                    StandBy.toTray = false; // reset in case it was set
                }
                else
                {
                    if (player_rec.State == VlcState.Playing)
                        player_rec.Stop();
                    player_rec = null;
                    vlc_rec = null;
                }
                if (Properties.Settings.Default.AllwaysOnTop == true)
                    this.TopMost = true;
                else
                    this.TopMost = false;
            }

            //stop vlc, dispose stuff
            if (cont)
            {
                killTimers();
                vlcStop();
                vlcDispose();
                if (httpreq != null)
                    httpreq.Dispose();
                if (epg != null)
                {
                    //unsubscribe
                    epg.Finished -= epg_Finished;
                    epg.Clean();
                }

                // if unicast was selected and vlc is responding then we must clear vlm elemnt.
                if (!Properties.Settings.Default.Multicast)
                {
                    if (Properties.Settings.Default.UnicastServer == "vlc")
                        vlmClearChannel(true);
                    else if (Properties.Settings.Default.UnicastServer == "udprelay")
                        udprClearChannel(true);
                }
            }
 
            saveFormSettings();
        }
        
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            // exit application 
            PasswordEncription.Unlocked = false;
            //enable screen saver if we disabled it
            if (Properties.Settings.Default.ScreenSaver)
                enableScreenSaver();

            if (!StandBy.toTray)
            {
                // scheduler check 1/2
                if (Globals.RecInstanceCount != 0)
                {
                    if (MessageBox.Show(MLmessages.RecAllowAbort, "", MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        // abort full exit and go only to tray
                        StandBy.sysTrayMenu.MenuItems[0].Enabled = false;
                        StandBy.sysTrayMenu.MenuItems[1].Enabled = false;
                        StandBy.mainform = null;
                        return;
                    }
                }
                // exit
                Application.Exit();
            }
            else
            {
                //reset  totray  
                StandBy.toTray = false;
                StandBy.mainform = null;
            }
        }

        private void killTimers()
        {
            // stop critical timers
            TimerStreamInfo.Dispose();
            TimerSurf.Dispose();
            TimerEpgListview.Dispose();
            TimerNetMonitor.Dispose();
            TimerNetMonitorGui.Dispose();
        }

        private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
        {
            saveFormSettings();
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.Close();
        }
       
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //exit
            this.Close();
        }

        #endregion


        #endregion

    }

    public class ChannelData
    {
        private string _ip;
        private string _name;
        private int _num=0;
        private string _node;
        private bool _locked;
        private bool _skip;

        public ChannelData(string ip, string name, int num, string node, bool locked, bool skip)
        {
            _ip = ip;
            _name = name;
            _num = num;
            _locked = locked;
            _skip = skip;
            _node = node;
        }

        public string Ip
        {
            get { return _ip; }
        }
        public string  Name
        {
            get { return _name; }
        }
        public int Num
        {
            get { return _num; }
        }
        public string Node
        {
            get { return _node; }
            set { _node = value; }
        }
        public bool Locked
        {
            get { return _locked; }
        }
        public bool Skip
        {
            get { return _skip; }
        }
    }
}
